Copying an AD user with New-ADUser -Instance from Get-ADUser returns cannot convert value error - powershell

I am trying to copy an AD user account as part of a larger script. It has worked in the past but is currently throwing this error:
Cannot bind parameter 'Instance'. Cannot convert value "CN=Test Tester,OU=etc..." to type
"Microsoft.ActiveDirectory.Management.ADUser". Error: "Cannot convert the "CN=Test Tester,OU=etc..."
value of type "Deserialized.Microsoft.ActiveDirectory.Management.ADUser" to type
"Microsoft.ActiveDirectory.Management.ADUser"
The relevant code:
$user_to_copy = test.tester
$user_to_copy_instance = Get-ADUser $user_to_copy
New-ADUser -Instance $user_to_copy_instance
I don't understand why it throws an error when trying to convert the value type as I'm following the documentation for the "-Instance" parameter as found here: https://learn.microsoft.com/en-us/powershell/module/addsadministration/new-aduser?view=win10-ps
Any help is greatly appreciated, thank you!

It sounds like you're running this in a remote session. When you get an object back from the server, because it went through serialization and deserialization, it's not really that object anymore. It's a "property bag": just the properties, but without the methods that go along with the real type. You can read more about that here if you'd like.
To avoid that, you can try running both commands in the same line:
New-ADUser -Instance (Get-ADUser $user_to_copy)
I don't know 100% that it will work, but it makes sense that it might.

Related

PowerShell: using #{Add=''} sometimes work and sometimes it does not

When an object can have multiple values on an object like, I use most of the time:
-Object #{Add=''} or -Object #{Remove=''}. But I notice that this not works all the time, than you need to set all the values because other wise it replaces the existing values.
For example, when I use:
Set-Mailbox "Contoso Executives" -GrantSendOnBehalfTo #{Add='tempassistants#contoso.com','tempassistants#contoso.com'}
The #{Add=''} is working. But when I use:
Set-RetentionPolicy "MRM Policy" -RetentionPolicyTagLinks #{Add='tag1','tag2'}
I get the following error:
Cannot convert value "System.Collections.Hashtable" to type
Why does this happens? RetentionPolicyTagLinks can have multiple values in the same way as GrantSendOnBehalfTo can have.
Your issue is within the format of your RetentionPolicyTagLinks parameter.
Try the documentation below to help you with storing it in a variable first:
https://learn.microsoft.com/en-us/exchange/add-or-remove-retention-tags-exchange-2013-help

Setting a DateTime to $null/empty using PowerShell and the SCSM cmdlets

I'm currently trying to sync additional attributes from the AD (Active Directory) for user objects in SCSM (System Center Service Manager) using a PowerShell script.
The extension I wrote for this, includes an attribute for the expiration date of a AD user account (DateTime value, named DateTimeAttribute in the example) if the user account doesn't expire it should be empty/null.
Using Import-SCSMInstance, which should be similar to a CSV import, it kind of works by passing "null" for the field. The problem is that Import-SCSMInstance seems to be quite unreliable and it doesn't offer any kind of information of why it works or doesn't work. Using Update-SCSMClassInstance seems to work a lot better but I can't figure out a way to clear the field using this and even using [DateTime]::MinValue will result in an error, stating that it's an invalid value.
So would anyone have an idea on how to clear the value using Update-SCSMClassInstance or figure out why Import-SCSMInstance might or might not work?
A simple example for this could look like the following:
$server = "<ServerName>"
$extensionGuid = "<GUID>"
Import-Module 'C:\Program Files\System Center 2012 R2\Service Manager\Powershell\System.Center.Service.Manager.psd1'
New-SCManagementGroupConnection -ComputerName $server
$extensionClass = Get-SCSMClass -Id $extensionGuid
$scsmUserObject = Get-SCSMClassInstance -Class $extensionClass -Filter 'UserName -eq "<User>"'
# Error
$scsmUserObject.DateTimeAttribute = ""
# Works but fails on Update-SCSMClassInstance
$scsmUserObject.DateTimeAttribute = $null
$scsmUserObject.DateTimeAttribute = [DateTime]::MinValue
# Works
$scsmUserObject.DateTimeAttribute = "01-01-1970"
Update-SCSMClassInstance -Instance $scsmUserObject
It seems that you can't clear a date once it's filled. When you write $null, it sets the date to 1-1-0001 01:00:00, which is an invalid date causing the update-scsmclassinstance to fail.
What we have set as a user's AD property when we don't want something to expire, is 2999-12-31 (yyyy-MM-dd). Perhaps this could help, although it's not directly what you asked for...
Also, you can use the pipeline to update a property in SCSM:
Get-SCSMClassInstance -Class $extensionClass -Filter 'UserName -eq "<User>"' | % {$_.DateTimeAttribute = <date>; $_} | update-scsmclassinstance
It doesn't look like it's currently possible to clear custom date attributes using the PowerShell cmdlets.

How do I use Set-ADuser with the -Instance parameter to update an attribute to blank?

We've been using Powershell to bulk update our AD for several years with data from a CSV file. The code is pretty straight forward:
$Empinfo = Import-CSV AFile.csv
$EmpAD = Get-Aduser someone
$EmpAD.Title = $EmpInfo.Title
$EmpAD.streetAddress = $Empifo.street
$EmpAD.PostalCode = $Empifo.zip
<snip>
Set-ADUser -Instance $EmpAD
Recently, the street and zip info have been blanked for some people due to organizational weirdness. When we run the same script and try to set, say streetAdress to nothing, Set-ADuser throws a "replace" error.
(Note that I tried setting streetaddress to a single space and it still failed.)
After much trial and error, today I was able to make it work by testing for blankness and using the following:
if (Empinfo.street -eq $null) {
Set-ADUser $EmpAD -Clear streetaddress,postalCode
} else {
$EmpAD.streetAddress = $Locations[$site].street
$EmpAD.PostalCode = $Locations[$site].zip
}
In other words, we have to issue a specific -Clear action to accomplish this.
Is this how we should expect this to work? I cannot see anything in the -Instance parameter docs that says you cannot empty an attribute in the manner we were trying.
Yes , you have to use -Clear like how you have already done in the sample code in order to accomplish this. Thats the correct way to do that.
Empty field is actually holding the attribute value as Null.
So clearing that is important.

PowerShell Error - Method Not Found

When using $Computer.StartsWith("WI-") I get the following error
Method invocation failed because [Microsoft.ActiveDirectory.Management.ADComputer] does not contain a method named 'StartsWith'
I am under the impression that this is a default method. Is there something I have to import to use this?
Try this instead
$env:COMPUTERNAME.StartsWith("WI-")
That error is pretty clear: an object of [Microsoft.ActiveDirectory.Management.ADComputer] type does not contain a method named 'StartsWith'.
Where the $Computer comes from? From Get-ADComputer cmdlet? Read How to list all AD computer object properties
Running $Computer | Get-Member | ft -AutoSize should prompt more.
Run $Computer.GetType() as well. For instance, next could work if $Computer is not an array:
$Computer.Name.StartsWith("WI-")
$Computer.CN.StartsWith("WI-")
$Computer.DisplayName.StartsWith("WI-")
However, next similar expressions could give another results:
$Computer.Name.ToUpper().StartsWith("WI-")
$Computer.CN.ToUpper().StartsWith("WI-")
$Computer.DisplayName.ToUpper().StartsWith("WI-")

Find and replace custom attribute values in AD using Powershell

So I have an interesting script I am trying to figure out, basically I need to change a custom attribute value to a new one. The problem is its for both users and computers and not specific to the groups. So for instance the value might be Billing1 for several users in an OU and this need to be Billing2. So I need to find any instance of the Value of Billing1 and change it to Billing2 not knowing the user or computer object. I can successfully change one at a time if I know who the user is by using Set-ADUser, Set-ADComputer and even with Set-AdObject but I need to figure out a Find and replace function.
I have searched for this and I have found examples of where I can use CSV for users and computers but again I don't know who has what since the value in the attribute can vary and also changes if a reorg happens.
got the correct script...
Get-ADComputer -Properties enterattributename -Filter {enterattributename -like "value to search" } |Set-ADComputer –replace #{ enterattributename =”value to change”}
this also can be applied to Get-ADUser and Get-ADObject