piping get-aduser output to set-aduser within a foreach loop - powershell

I am trying to get a list of users where the telephone attrib is null and update the atrrib with a phone number, so far here is what I have:
$allen=gc "C:\0NIX\03SCRIPTS\TMP\jkirb\allen.txt"
$phonenumber = "972-xxx-xxx"
FOREACH ($user in $allen)
{
$nophone = get-aduser $user -pr *| where {$_.telephonenumber -eq $null} | select samaccountname |ft -HideTableHeaders
Set-ADuser -identity "$nophone" -replace #{telephonenumber="$phonenumber"}
}
Which is erroring with this:
Set-ADuser : Cannot find an object with identity: 'Microsoft.PowerShell.Commands.Internal.Format.FormatStartData Microsoft.PowerShell.Commands.Internal.Format.GroupStartData
Microsoft.PowerShell.Commands.Internal.Format.FormatEntryData Microsoft.PowerShell.Commands.Internal.Format.GroupEndData Microsoft.PowerShell.Commands.Internal.Format.FormatEndData' under:
'DC=bhcs,DC=pvt'.
At line:7 char:1
+ Set-ADuser -identity "$nophone" -replace #{telephonenumber="$phonenumber"}
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : ObjectNotFound: (Microsoft.Power...t.FormatEndData:ADUser) [Set-ADUser], ADIdentityNotFoundException
+ FullyQualifiedErrorId : Cannot find an object with identity: 'Microsoft.PowerShell.Commands.Internal.Format.FormatStartData Microsoft.PowerShell.Commands.Internal.Format.GroupStartData Mic
rosoft.PowerShell.Commands.Internal.Format.FormatEntryData Microsoft.PowerShell.Commands.Internal.Format.GroupEndData Microsoft.PowerShell.Commands.Internal.Format.FormatEndData' under: 'DC=
bhcs,DC=pvt'.,Microsoft.ActiveDirectory.Management.Commands.SetADUser

You are adding some custom formatting to your object when you use any of the Format-* cmdlets (Format-Table in your case) and this ruins the object for future pipeline use.
Try this instead:
$allen=gc "C:\0NIX\03SCRIPTS\TMP\jkirb\allen.txt"
$phonenumber = "972-xxx-xxx"
FOREACH ($user in $allen)
{
$nophone = get-aduser $user -pr *| where {$_.telephonenumber -eq $null}
Set-ADuser -identity "$nophone" -replace #{telephonenumber="$phonenumber"}
}

Related

Update Active Directory (On-Prem) User Attribute via Powershell

I tried to not bug you all, but I'm at a loss. I'll preface with, I'm still relatively new to PS, so my apologies for any ignorance.
Need: To update users' attribute (extensionAttribute1 to be precise) to "First.Last" (or rather, "givenName.Surname") for all users in AD.
Problem: When I try to run the Powershell below (I was trying 2 different methods for update, hence the commented out portion), I get the outputs below.
Import-Module ActiveDirectory
Get-ADUser -Filter * -SearchBase 'ou=Users,ou=Test,dc=Sample,dc=Com' |
Select SamAccountName |
Export-Csv -Path 'c:\Scripts\AllUsersSamaccountname.CSV' -NoTypeInformation
$file="c:\Scripts\AllUsersSamaccountname.CSV"
(gc $file | select -Skip 1) | sc $file
$Users = Import-Csv -Path "c:\Scripts\AllUsersSamaccountname.CSV" -Header "AccountName"
foreach($User in $Users){
$ADUser = Get-ADUser -Identity $User.AccountName -Properties extensionAttribute1
$ADUserG = Get-ADUser -Identity $User.AccountName -Properties givenName
$ADUserS = Get-ADUser -Identity $User.AccountName -Properties Surname
#$ADUser.extensionAttribute1 = [Array]$ADUserG + '.' + $ADUserS
Set-ADUser -Instance $ADUser -replace #{extensionAttribute1=([Array]$ADUserG + '.' + $ADUserS)}
}
Get-ADUser -Filter * -SearchBase 'ou=Users,ou=Test,dc=George,dc=Com' |
Select extensionAttribute1 |
Export-Csv -Path 'c:\Scripts\new-AllUserinfo6.CSV' -NoTypeInformation
Output for Set-ADUser -Instance $ADUser -replace #{extensionAttribute1=([Array]$ADUserG + '.' + $ADUserS)
Set-ADUser : Cannot validate argument on parameter 'Replace'. All values in the argument collection should be of
the same type.
At line:17 char:44
+ ... er -replace #{extensionAttribute1=([Array]$ADUserG + '.' + $ADUserS)} ...
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : InvalidData: (:) [Set-ADUser], ParameterBindingValidationException
+ FullyQualifiedErrorId : ParameterArgumentValidationError,Microsoft.ActiveDirectory.Management.Commands.Set
ADUser
Output for #$ADUser.extensionAttribute1 = [Array]$ADUserG + '.' + $ADUserS
Exception setting "extensionAttribute1": "The adapter cannot set the value of property "extensionAttribute1"."
At line:16 char:6
+ $ADUser.extensionAttribute1 = [Array]$ADUserG + '.' + $ADUserS
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : NotSpecified: (:) [], SetValueInvocationException
+ FullyQualifiedErrorId : CatchFromBaseAdapterSetValue
Any help or guidance would be greatly appreciated...
You are casting the givenName to an array. More than likely that's causing the whole expression to return an array, which isn't acceptable for extensionAttribute1.
I didn't test this but rewriting the loop to something like below should work:
foreach($User in $Users)
{
$ADUser = Get-ADUser -Identity $User.AccountName -Properties extensionAttribute1
$ADUserG = Get-ADUser -Identity $User.AccountName -Properties givenName
$ADUserS = Get-ADUser -Identity $User.AccountName -Properties Surname
$extensionAttribute1 = ($ADUserG.givenName + '.' + $ADUserS.Surname)
$ADUser.extensionAttribute1 = $extensionAttribute1
Set-ADUser -Instance $ADUser
}
Note: that you must reference the properties for givenName & Surname in order to concatenate them as strings. Otherwise you are trying to add 2 user objects together and will get an error.
Additional Info:
If this were me I would write this to be more concise. However, considering you are relatively new to PowerShell, I'd just make one recommendation. In the loop you don't need to get the user account multiple times, something like the below should work and be a little faster.
Import-Module ActiveDirectory
Get-ADUser -Filter * -SearchBase 'ou=Users,ou=Test,dc=Sample,dc=Com' |
Select-Object SamAccountName |
Export-Csv -Path 'c:\Scripts\AllUsersSamaccountname.CSV' -NoTypeInformation
$file="c:\Scripts\AllUsersSamaccountname.CSV"
(Get-Content $file | Select-Object -Skip 1) | Set-Content $file
$Users = (Import-Csv -Path "c:\Scripts\AllUsersSamaccountname.CSV" -Header "AccountName")
foreach($User in $Users)
{
$ADUser = Get-ADUser -Identity $User.AccountName -Properties 'extensionAttribute1','givenName','Surname'
$extensionAttribute1 = ($ADUser.givenName + '.' + $ADUser.Surname)
$ADUser.extensionAttribute1 = $extensionAttribute1
Set-ADUser -Instance $ADUser
}
Get-ADUser -Filter * -SearchBase 'ou=Users,ou=Test,dc=George,dc=Com' |
Select-Object extensionAttribute1 |
Export-Csv -Path 'c:\Scripts\new-AllUserinfo6.CSV' -NoTypeInformation

Updating Active Directory Manager Attribute from .csv Using PowerShell

I'm not so good at PowerShell. I have this script which worked before that I've have used to update the manager attribute in Active Directory, however, now after just replacing the file its no longer working
$Users = Import-CSV C:\Documents\Managers.csv
ForEach ($User in $Users) {
$user= Get-ADUser -Filter "displayname -eq '$($Users.EmployeeFullName)'"|select -ExpandProperty samaccountname
$manager=Get-ADUser -Filter "displayname -eq '$($Users.'Line Manager Fullname')'"|select -ExpandProperty DistinguishedName
Set-ADUser -Identity $user -Replace #{manager=$manager}
}
when running the script it returns:
Set-ADUser : Cannot validate argument on parameter 'Identity'. The argument is null. Provide a valid value for the argument, and then try running the command again.
At line:6 char:22
+ Set-ADUser -Identity $user -Replace #{manager=$manager}
+ ~~~~~
+ CategoryInfo : InvalidData: (:) [Set-ADUser], ParentContainsErrorRecordException
+ FullyQualifiedErrorId : ParameterArgumentValidationError,Microsoft.ActiveDirectory.Management.Commands.SetADUser
the "EmployeeFullName" and "Line Manager FullName" format in the .csv is set as i.e. joe bloggs, see below CSV file example.
EmployeeFullname Line Manager Fullname
---------------- ---------------------
Kieran Rhodes Tracey Barley
Lewis Pontin Tracey Barley
Lizzy Wilks Rodney Bennett
I also noticed if I remove and try to retype "$Users.EmployeeFullName" it no longer picks up the "EmployeeFullName" from the csv file.
Anyone know what I'm doing wrong here please?
Below would be an example:
$Users = Import-CSV C:\Documents\Managers.csv
ForEach ($User in $Users) {
$user = Get-ADUser -Filter "displayname -eq '$($User.EmployeeFullName)'"
$manager = (Get-ADUser -Filter "displayname -eq '$($User.'Line Manager Fullname')'").DistinguishedName
Set-ADUser -Identity $User -Replace #{manager=$manager}
}
Note: you don't need to dig down to the samAccountName property because Set-ADUser will take the full fidelity object for the -Identity argument. You also don't need to use Select... -ExpandProperty you can just parenthetically dot reference the distinguishedName property.
Also you can use the instancing capability in the AD cmdlets:
$Users = Import-CSV C:\Documents\Managers.csv
ForEach ( $User in $Users )
{
$User = Get-ADUser -Filter "displayname -eq '$($User.EmployeeFullName)'" -Properties Manager
$Manager = (Get-ADUser -Filter "displayname -eq '$($User.'Line Manager Fullname')'").DistinguishedName
$User.Manager = $Manager
Set-ADUser -Instance $User
}
In this case you call back the Manager property set it with a simple assignment statement than give the $User variable as the argument to the -Instance parameter of Set-ADUser

How do I pass SamAccountName from a given user name, so that I can set -ProtectedfromAccidentalDeletion#$true

I inherited several PowerShell scripts, to place a user on LitigationHold in Exchange, as well as set the user's AD protect from accidental deletion to $true.
They all work separately, but one uses User Full name, and the other uses the SAM account name. I am trying to marry scripts so that I can just use the Full name, but I can't seem to pass the SAMAccountName .
My attempt at combining the codes:
foreach ($user in ("Name 1", "Name 2", "Name 3"))
{
$mailuser = Get-Mailbox $user -DomainController A1.Domain l -ErrorAction SilentlyContinue| Select *;
if ($mailuser -eq $null)
{
Write-Host "$user was not found. Check for misspellings."
}
else
{
if($mailuser.LitigationHoldDate -ne $null)
{
Set-Mailbox $user -LitigationHoldEnabled:$true -Confirm:$False -Force:$True -DomainController A1.Domain;
Write-Host "$user is now placed on hold.";
$userinfo = {
Get-ADUser $user -Server A1.Domain
};
Set-ADObject -Identity $userinfo.SamAccountName -ProtectedFromAccidentalDeletion:$true;
$i = Get-ADUser $user -Properties description -Server A1.Domain |
%{ $_.description } |
Set-ADUser $userinfo -Server A1.Domain -Replace #{
description="8/19/2019 - Security Hold, please contact admin before modifying `r`n | $($i)"
}
}
else{
Write-Host "$user is already on litigation hold as of $($mailuser.LitigationHoldDate) by $($mailuser.LitigationHoldOwner)."
}
}
}
To take list of Display names and get usernames:
foreach ($user in ("Name 1", "Name 2", "Name 3"))
{
$userinfo = Get-ADUser -filter { DisplayName -like $user } -Server A1.Domain ;
if ($userinfo -ne $null)
{
Get-ADUser -filter { DisplayName -like $user } -Server A1.Domain | ft SamAccountName -HideTableHeaders
}
else
{
Write-Host "$user is not available"
}
}
To Add Lit Hold into AD Description
foreach ($user in ("Name 1", "Name 2", "Name 3"))
{
$mailuser = Get-Mailbox $user -DomainController A1.Domain -ErrorAction SilentlyContinue| Select *;
if($mailuser -eq $null)
{
Write-Host "$user was not found. Check for misspellings."
}
else
{
if ($mailuser.LitigationHoldDate -eq $null)
{
$i = Get-ADUser $user -Properties description -Server A1.Domain | %{ $_.description};
Set-ADUser $user -Server A1.Domain -Replace #{
description="Security Hold, please contact the Gnome before modifying `r`n | $($i)"
}
}
else
{
Write-Host "$user is already on litigation hold as of $($mailuser.LitigationHoldDate) by $($mailuser.LitigationHoldOwner)."
}
}
}
To take a list of Display names and set Lit Hold:
foreach ($user in ("Name 1", "Name 2", "Name 3""))
{
$mailuser = Get-Mailbox $user -DomainController A1.Domain -ErrorAction SilentlyContinue| Select *;
if ($mailuser -eq $null)
{
Write-Host "$user was not found. Check for misspellings."
}
else
{
if($mailuser.LitigationHoldDate -eq $null)
{
Set-Mailbox $user -LitigationHoldEnabled:$true -Confirm:$False -Force:$True -DomainController A1.Domain ;
Write-Host "$user is now placed on hold."
}
else
{
Write-Host "$user is already on litigation hold as of $($mailuser.LitigationHoldDate) by $($mailuser.LitigationHoldOwner)."
}
}
}
To take a list of usernames and protect against accidental deletion:
"User1", "User2", "User3" | Get-aduser -Server A1.Domain | Set-ADObject -ProtectedFromAccidentalDeletion:$true
I want to account to be set to LitigationHold, AD protect from accidental deletion, also reflect security hold on description.
This is the error message I get when I run it:
FN LN is now placed on hold.
Set-ADObject : Cannot validate argument on parameter 'Identity'. The argument is null. Provide a valid value for the argument, and then try running the
command again.
At line:9 char:25
+ Set-ADObject -Identity $userinfo.SamAccountName -ProtectedFromAccide ...
+ ~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : InvalidData: (:) [Set-ADObject], ParameterBindingValidationException
+ FullyQualifiedErrorId : ParameterArgumentValidationError,Microsoft.ActiveDirectory.Management.Commands.SetADObject
Set-ADUser : A positional parameter cannot be found that accepts argument 'Get-ADUser $user -Server A1.domain '.
At line:12 char:1
+ Set-ADUser $userinfo -Server A1.domain -Replace # ...
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : InvalidArgument: (:) [Set-ADUser], ParameterBindingException
+ FullyQualifiedErrorId : PositionalParameterNotFound,Microsoft.ActiveDirectory.Management.Commands.SetADUser
I was trying to see if I can bypass the -Identify flag by giving it the user full name, but Set-ADObject will only take an object, not a string.
--edit 3--
Replying to #Seth about -Identity flag is a parameter:
changed part of the code to give -Identity an ADObject:
$userinfo = Get-ADUser {DisplayName -like $user} -Server A1.domain};
Set-ADObject $userinfo -ProtectedFromAccidentalDeletion:$true;
The error message is as follows:
Get-ADUser : Cannot evaluate parameter 'Identity' because its argument is specified as a script block and there is no input. A script block cannot be
evaluated without input.
At line:8 char:26
+ $userinfo = Get-ADUser {DisplayName -like $user} -Server A1.domain ...
+ ~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : MetadataError: (:) [Get-ADUser], ParameterBindingException
+ FullyQualifiedErrorId : ScriptBlockArgumentNoInput,Microsoft.ActiveDirectory.Management.Commands.GetADUser
Set-ADObject : Cannot evaluate parameter 'Identity' because its argument is specified as a script block and there is no input. A script block cannot be
evaluated without input.
At line:9 char:15
+ Set-ADObject $userinfo -ProtectedFromAccidentalDeletion:$true;
+ ~~~~~~~~~
+ CategoryInfo : MetadataError: (:) [Set-ADObject], ParameterBindingException
+ FullyQualifiedErrorId : ScriptBlockArgumentNoInput,Microsoft.ActiveDirectory.Management.Commands.SetADObject
Set-ADUser : A positional parameter cannot be found that accepts argument 'Get-ADUser {DisplayName -like $user} -Server A1.domain'.
At line:12 char:1
+ Set-ADUser $userinfo -Server A1.domain -Replace # ...
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : InvalidArgument: (:) [Set-ADUser], ParameterBindingException
+ FullyQualifiedErrorId : PositionalParameterNotFound,Microsoft.ActiveDirectory.Management.Commands.SetADUser
I think at this point the issue boils down to: Set-ADUser uses SamAccountName, and I can't seem to parse out the SamAccountName from the user ADObject. I can get the SamAccountName by calling a table from the ADObject, but it will not pass into Set-ADUser correctly.
You're currently not doing any verification on whenever you actually get a proper ADUser object. You simply assume that the assignment to $i/$userinfo will be successful. Your $name contains the display name for a user. So for example it would be "John Doe".
This works for Get-Mailbox because it supports Name, Alias, Distinguished name (DN), Canonical DN, <domain name>\<account name>, Email address, GUID, LegacyExchangeDN, SamAccountName, User ID or user principal name (UPN) as values for Identity. It has to do this to an extend because some values might or might not be available to identify a mailbox. Get-ADUser on the other hand has a much more strict approach only supporting distinguished name, GUID (objectGUID), security identifier (objectSid), SAM account name (sAMAccountName). Hence using the display name to find an AD account isn't supported. Your colleague used a filter to just use it anyway which is one solution $userinfo = Get-ADUser -filter { DisplayName -like $user } -Server A1.Domain ;.
If you really want to go with the display name you'll need to either look for it like that or use the DistinguishedName property of the mailbox to get the owner. So you'd do something like:
$mailbox = Get-Mailbox test
$adObject = Get-AdUser -Identity $mailbox.DistinguishedName
Obviously you should check whenever the property actually exists on the mailbox object as it might be disconnected. Also rather than using $user again and again you might want to use actual object (e.g. the mailbox or AD Object) to make sure you only need to verify your search results once.
You should also be able to just use one Set-AdUser call instead of that very weird call you're currently doing. You find the user, iterate the descriptions for the user (an object only has one) and add to it. Doing something like Set-AdUser $adObject -Description "New Description | $($adObject.Description)" would be much shorter and clearer. Spreading it some more might even improve it more.

Script to add users of particular AD OU to another AD group

Running Powershell as an admin
I would like to have a script that I can run daily to add users from "cn=users,dc=costco,dc=com" to an AD group "groupname" "CN=groupname,OU=Groups,DC=costco,DC=com"
$When = (Get-Date).AddDays(-1).Date
Get-ADUser -SearchBase 'cn=users,dc=costco,dc=com' -Filter { whenCreated -ge $When } | add-adgroupmember -MemberOf 'groupname'
it errors out with
Add-ADGroupMember : A parameter cannot be found that matches parameter
name 'MemberOf'. At line:2 char:111
+ ... ilter { whenCreated -ge $When } | add-adgroupmember -MemberOf 'groupname ...
+ ~~~~~~~~~
+ CategoryInfo : InvalidArgument: (:) [Add-ADGroupMember], ParameterBindingException
+ FullyQualifiedErrorId : NamedParameterNotFound,Microsoft.ActiveDirectory.Management.Commands.AddADGroupMember
I have also tried with the help of a redditor
When = (Get-Date).AddDays(-1).Date
Get-ADUser -SearchBase 'CN=users,dc=costo,dc=com' -Filter { whenCreated -ge $When } | ForEach-Object { Add-ADGroupMember -Identity 'Groupname' -Members $_ }
Error:
Add-ADGroupMember : Insufficient access rights to perform the
operation At line:2 char:109
+ ... ach-Object {Add-ADGroupMember -Identity ‘groupname’ -Members $_ } ...
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : NotSpecified: (groupname:ADGroup) [Add-ADGroupMember], ADException
+ FullyQualifiedErrorId : ActiveDirectoryServer:8344,Microsoft.ActiveDirectory.Management.Commands.AddADGroupMember
To make your first example work, you need to supply the pipeline value to the command, instead of trying to pass it in on the actual pipeline.
Try:
$group = "NewUsers"
Get-ADUser -SearchBase 'cn=users,dc=costco,dc=com' -Filter { whenCreated -ge $When } | %{ Add-ADGroupMember -Identity $Group -Members $_.samaccountname }

How to populate the manager field on Active Directory, using powerShell

Im trying to populate the manager fields on AD using
Import-Csv C:\Testimport.csv | ForEach-Object {Set-ADUser -Identity $_.samAccountName -Replace #{Manager=$_.manager}}
But I get the following error:
Set-ADUser : Cannot bind parameter 'Replace' to the target. Exception
setting " Replace": "Object reference not set to an instance of an
object." At line:1 char:95
+ Import-Csv C:\Testimport.csv | ForEach-Object {Set-ADUser -Identity $.samAcc ountName -Replace <<<< #{manager=$.manager}}
+ CategoryInfo : WriteError: (:) [Set-ADUser], ParameterBindingEx ception
+ FullyQualifiedErrorId : ParameterBindingFailed,Microsoft.ActiveDirectory
.Management.Commands.SetADUser
Depending on what the Manager is represented by in your csv you can just use the Set-Aduser parameter -Manager on its own.
Import-Csv C:\Testimport.csv | ForEach-Object {Set-ADUser -Identity $_.samAccountName -Manager $_.manager}
If not please show some sample date in your question. This would work in Manager was a account name at least. Also there is an error in the code you ran: manager=$.manager should be manager=$_.manager
If $_.manager is the Manager sAMAccountName attribute, you need the distinguidhedName attribute to use it later as a value into -Replace parameter:
Import-Csv C:\Testimport.csv |
ForEach-Object {
$managerDN = (Get-ADUser $_.manager).distinguishedName
Set-ADUser -Identity $_.samAccountName -Replace #{Manager=$managerDN}
}