Error when changing AD properties in Powershell - powershell

Trying to change msexchhidefromaddresslists property from Powershell for a specific user account. I did a search and found a basic script but am getting an error. I have tried directly from my system and fromm the server. Any ideas?
set-aduser ldap -replace #{msexchhidefromaddresslists="$true"}
set-aduser : The parameter is incorrect
At line:1 char:1
+ set-aduser ldap -replace #{msexchhidefromaddresslists="$true"}
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : InvalidOperation: (ldap:ADUser) [Set-ADUser], ADInvalidOperationException
+ FullyQualifiedErrorId : ActiveDirectoryServer:87,Microsoft.ActiveDirectory.Management.Commands.SetADUser

The schema for the msExchHideFromAddressLists attribute specifies oMSyntax: 1, or Boolean.
LDAP allows a couple different representations of booleans, including integral values (0 for false, a non-zero value for true), or, more commonly the lower-case string representations true or false.
"$true", on the other hand, results in a string with value True (notice it's title-cased, not lowercase).
Use one of:
#{msExchHideFromAddressLists = 1}
#{msExchHideFromAddressLists = "true"} or
#{msExchHideFromAddressLists = $True}
In the last case, the $true value will be (correctly) translated by ADWS, rather than (incorrectly) by PowerShell's string conversion logic

Related

Powershell Registry String to Workable Date

Cannot convert string format to date using parse exact.
Registry contains the following string value:
2022-10-18T12:40:25
I need to convert this string to a date field in order to count number of days since (compared to today).
$startdate =
Get-ItemProperty -Path 'HKLM:SOFTWARE\Adobe\Acrobat Distiller\DC\Installer\' |
select-object 'Dummy'
[datetime]::parseexact($startdate,'dd/MM/yyyy HH:mm',$null)
$today = (([datetime]::Now))
$x = New-TimeSpan -Start $startdate -End $today
"$($x.days) $("days have passed since") $($startdate)"
Cannot find an overload for "parseexact" and the argument count: "3".
At line:2 char:1
+ [datetime]::parseexact($startdate,'dd/MM/yyyy HH:mm',$null)
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : NotSpecified: (:) [], MethodException
+ FullyQualifiedErrorId : MethodCountCouldNotFindBest
New-TimeSpan : Cannot bind parameter 'Start'. Cannot convert value "#{dummy=2022-10-18T12:40:25}" to type "System.DateTime". Error: "Cannot convert the "#{dummy=2022-10-18T12:40:25}" value of type
"Selected.System.Management.Automation.PSCustomObject" to type "System.DateTime"."
At line:5 char:26
+ $x = New-TimeSpan -Start $startdate -End $today
+ ~~~~~~~~~~
+ CategoryInfo : InvalidArgument: (:) [New-TimeSpan], ParameterBindingException
+ FullyQualifiedErrorId : CannotConvertArgumentNoMessage,Microsoft.PowerShell.Commands.NewTimeSpanCommand
days have passed since #{dummy=2022-10-18T12:40:25}
Your primary problem is that you need to use -ExpandProperty, if you use Select-Object, or you can use simple property access:
Select-Object (select) by default returns a [pscustomobject] instance that has the requested properties - even when you're only asking for a single property. To get only that property's value, use the -ExpandProperty parameter instead of the (possibly positionally implied) -Property parameter - see this answer for details and alternatives, notably the ability to simply use (...).SomeProperty
Therefore, the simplest solution is:
$startdate = (
Get-ItemProperty 'HKLM:SOFTWARE\Adobe\Acrobat Distiller\DC\Installer'
).Dummy
Or, in PSv5+, using Get-ItemPropertyValue:
$startdate =
Get-ItemPropertyValue 'HKLM:SOFTWARE\Adobe\Acrobat Distiller\DC\Installer' Dummy
As for then parsing the resulting string into a [datetime] instance:
The format string you're passing to ::ParseExact(), doesn't match your input string, and TheMadTechnician's answer shows how to fix that (see this answer's bottom section for further considerations).
However, you can more simply use a [datetime] cast, which recognizes your string format as-is, irrespective of what culture is currently in effect:
[datetime] '2022-10-18T12:40:25'
In essence, PowerShell translates the above into the following ::Parse() call:
[datetime]::Parse('2022-10-18T12:40:25', [cultureinfo]::InvariantCulture)
In general, for full robustness when using format strings, it is best to escape :, /, and . (if present) with \, so as if they are to be interpreted literally, i.e by only matching literally during parsing and being included literally when formatting output (by default, they're considered placeholders for the target culture's separators):
[datetime]::ParseExact(
'2022-10-18T12:40:25',
'yyyy-MM-ddTHH\:mm\:ss', # \-escaping ensures literal matching
[cultureinfo]::InvariantCulture
)
Note: In this particular case, [cultureinfo]::InvariantCulture alone would be sufficient for robustness, given that this culture uses : as the time separator.
You get an error because your second argument doesn't match the format of the datetime.
[datetime]::parseexact($startdate,'yyyy-MM-ddTHH:mm:ss',$null)

Separating values entered into a string

So I am trying to create a Powershell menu that when the user selects a choice, it will ask for the value or values its trying to search (ex. Ping Multiple Computers). I am currently having a hard time getting that to work. I will post pictures to show what I mean
When I type in one name to search the command executes fine shown below:
When I try with multiple values it doesn't work:
Here is a snap of the code I have:
Any help of course is much appreciated.
UPDATE - 11/13
This is what I currently have:
function gadc {
Param(
[Parameter(Mandatory=$true)]
[string[]] $cname # Note: [string[]] (array), not [string]
)
$cname = "mw$cname"
Get-ADComputer $cname
}
This is the output in the Console
cmdlet gadc at command pipeline position 1
Supply values for the following parameters:
cname[0]: imanuel
cname[1]: troyw
cname[2]: hassan
cname[3]:
Get-ADComputer : Cannot convert 'System.String[]' to the type
'Microsoft.ActiveDirectory.Management.ADComputer' required by parameter 'Identity'. Specified
method is not supported.
At line:32 char:19
+ Get-ADComputer $cname
+ ~~~~~~
+ CategoryInfo : InvalidArgument: (:) [Get-ADComputer], ParameterBindingException
+ FullyQualifiedErrorId : CannotConvertArgument,Microsoft.ActiveDirectory.Management.Commands.G
etADComputer
Press Enter to continue...:
**And here is the other way with the same result:**
cmdlet gadc at command pipeline position 1
Supply values for the following parameters:
cname[0]: imanuel, troyw
Get-ADComputer : Cannot convert 'System.String[]' to the type
'Microsoft.ActiveDirectory.Management.ADComputer' required by parameter 'Identity'. Specified
method is not supported.
At line:32 char:19
+ Get-ADComputer $cname
+ ~~~~~~
+ CategoryInfo : InvalidArgument: (:) [Get-ADComputer], ParameterBindingException
+ FullyQualifiedErrorId : CannotConvertArgument,Microsoft.ActiveDirectory.Management.Commands.G
etADComputer
Press Enter to continue...:
You need to declare your mandatory parameter as an array, then PowerShell's automatic prompting will allow you to enter multiple values, one by one - simply press Enter by itself after having submitted the last value in order to continue:
function gadc {
param(
[Parameter(Mandatory)]
[string[]] $cname # Note: [string[]] (array), not [string]
)
# Get-ADComputer only accepts one computer name at a time
# (via the positionally implied -Identity parameter), so you must loop
# over the names.
# The following should work too, but is slightly slower:
# $cname | Get-ADComputer
foreach ($c in $cname) { Get-ADComputer $c }
}

Changing msExchRequireAuthToSendTo on AD group back to "Not Set"

We run a "hybrid" Exchange environment where Office365 looks at some attributes on AD groups. One of the ExtendedAttributes, msExchRequireAuthToSendTo, controls whether or not an "outside" user can send to a distribution list held in AD.
This ExtendedAttribute has three possible settings: True / False / "Not Set" - in order to prevent "outside" users from sending spam, the value has to be True. The default is "Not Set".
I can set either True or False like this:
$InternalDistro = (Get-ADGroup -filter 'name -eq "CoolDistroList"')
Set-ADGroup $InternalDistro -Replace #{msExchRequireAuthToSendTo = $False}
Is there a way to set the value BACK to the default value of "Not Set"? I tried $Null but that returns an error:
Set-ADGroup : Cannot bind parameter 'Replace' to the target. Exception setting "Replace": "Object reference not set to an
instance of an object."
At line:2 char:38
+ ... ADGroup $InternalDistro -Replace #{msExchRequireAuthToSendTo = $Null}
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : WriteError: (:) [Set-ADGroup], ParameterBindingException
+ FullyQualifiedErrorId : ParameterBindingFailed,Microsoft.ActiveDirectory.Management.Commands.SetADGroup
Any suggestions would be appreciated - thanks for thinking about this!
Is there a purpose to setting it back to 'Not Set' rather than
'False'? If so use the -Clear parameter: Set-ADGroup $InternalDistro
-Clear 'msExchRequireAuthToSendTo' – TheMadTechnician
This works perfectly, posting as the answer - all credit to #TheMadTechnician!

Putting together an ADSI LDAP query

I am searching through the active directory for users under a specific organisation unit, that I would like to change using ADSI.
# get all users from the organizational unit
$accounts = Get-ADObject -filter 'objectClass -eq "user"' -SearchBase $dsn
# iterate over user objects
foreach ($account in $accounts) {
# unfortunately we have to use ADSI over the set-aduser cmdlet as we neeed to touch remote desktop attribues
$user = [ADSI]"LDAP://" + ($account.DistinguishedName).ToString()
# get logon name
$SamAccountName = $user.psbase.InvokeGet("SamAccountName")
# Profile Attributes
$user.psbase.InvokeSet("ProfilePath", "")
$user.psbase.InvokeSet("ScriptPath", "DIR\Logon.cmd")
$user.psbase.InvokeSet("HomeDrive", "H:")
$user.psbase.InvokeSet("HomeDirectory", "\\host\users$\${SamAccountName}")
# Remote Desktop Services Attributes
$user.psbase.InvokeSet("TerminalServicesProfilePath", "")
$user.psbase.InvokeSet("TerminalServicesHomeDirectory", "\\host\users$\${SamAccountName}")
$user.psbase.InvokeSet("TerminalServicesHomeDrive", "H:")
# Write attributes back to global catalog
$user.SetInfo()
}
This all works fine, until it comes to the $user = [ADSI]"LDAP://" + ($account.DistinguishedName).ToString() part.
Method invocation failed because [System.DirectoryServices.DirectoryEntry] does not contain a method named 'op_Addition'.
At \\tsclient\D\SourceCode\PowerShell\Set-ADUserAttributes.ps1:37 char:5
+ $user = [ADSI]"LDAP://" + ($account.DistinguishedName).ToString()
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : InvalidOperation: (op_Addition:String) [], RuntimeException
+ FullyQualifiedErrorId : MethodNotFound
Exception calling "InvokeGet" with "1" argument(s): "Unspecified error
"
At \\tsclient\D\SourceCode\PowerShell\Set-ADUserAttributes.ps1:40 char:5
+ $SamAccountName = $user.psbase.InvokeGet("SamAccountName")
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : NotSpecified: (:) [], MethodInvocationException
+ FullyQualifiedErrorId : DotNetMethodException
It seems there is no query getting executed. However, $account.DistinguishedName contains the correct LDAP path (which I have tested manually).
So what am I doing wrong here?.
You're trying to append to an ADSI object by casting "LDAP://" as [ADSI] before you do the append.
Cat your strings first, then do the cast:
$user = [ADSI]("LDAP://" + $account.DistinguishedName)
The casting operation has higher precedence than the concatenation operation, so you need to do the concatenation in a subexpression, either like this:
[adsi]("LDAP://" + $account.DistinguishedName)
or like this:
[adsi]"LDAP://$($account.DistinguishedName)"
The distinguished name is automatically converted to a string here, so you don't need to manually call ToString().

Method Invocation failed system.string error

Morning,
I'm trying to use a CSV file with a list of users and automate the process to set an AD users extensionAttribute15 back to the "notset" value.
I use a similar code to populate the attribute, the CSV file consists of just two things, the users LAN ID and the value for the attribute.
Populating the field is not the problem, changing the values back to "not set" has been.
Here is the code I am using.
Import-module ActiveDirectory
Import-CSV "code.csv" | % {
$User = $_.cn
$user.Put(“extensionAttribute15”, #())
$user.SetInfo()
}
and here are the errors.
Method invocation failed because [System.String] doesn't contain a method named 'Put'.
At attribute.ps1:4 char:10
+ $user.Put <<<< (“extensionAttribute15”, #())
+ CategoryInfo : InvalidOperation: (Put:String) [], RuntimeException
+ FullyQualifiedErrorId : MethodNotFound
Method invocation failed because [System.String] doesn't contain a method named 'SetInfo'.
At attribute.ps1:5 char:14
+ $user.SetInfo <<<< ()
+ CategoryInfo : InvalidOperation: (SetInfo:String) [], RuntimeException
+ FullyQualifiedErrorId : MethodNotFound
Any ideas what the problem could be?
Thanks,
When you read in a CSV file, the resulting objects are just simple property bags. They don't support any special methods, they just hold flat data. There is nothing in these objects that isn't present in the text of the CSV file itself.
If you want to obtain a rich object which has Active Directory context and capabilities, you will need to obtain one from a cmdlet in the ActiveDirectory module.
Something like this is probably along the lines you need
Import-module ActiveDirectory
Import-CSV "code.csv" | % {
$user = Get-ADUser $_.cn # get a rich object from the AD module, by passing a string
$user.Put(“extensionAttribute15”, #())
$user.SetInfo()
}