Organizing Active Directory accounts - powershell

I am trying to get a script to work that will organize my active directory accounts based off of their display name since all of our accounts have their OU in their name (or a subOU). I am trying to do this with an If statement inside of a ForEach loop in PowerShell. Every time I run it though, it keeps asking me for an identity. Can anyone help me fix this? This is what I have...
Import-Module ActiveDirectory
$OU = "OU=Test, OU=com"
$Test1OU = "OU=Test1, OU=Test, OU=Com"
$Test2OU = "OU=Test2, OU=Test, OU=Com"
$Users = (Get-ADUser -SearchBase $OU -Filter * -Properties samAccountName,DisplayName)
ForEach ($user in $users)
{
If ($($user.DisplayName -like ("*Supply*" -or "*Supplies*"))
{Move-ADObject -Identity $($user.samAccountName -TargetPath $Test1OU}
ElseIf ($($user.DisplayName -like ("*Accounting*" -or "*Accountant*"))
{Move-AdObject -TargetPath $Test2OU}
}

You are running into a few problems here
Like Vesper said you are not passing anything to Move-ADObject hence the error you are getting
$DisplayNames is not a string array of names but an object with a displayname property. That is what -ExpandProperty parameter is for with Select-Object FYI.
You are pulling all the users but only really want to process certain ones. Instead of -Filter * lets use a more targeted approach.
While it is tempting you cant nest -like conditions like that. If you take "*Supply*" -or "*Supplies*" and type that it will evaluate to true. Same as all non zero length strings.
For what we plan on doing we will not have to address all those issues. We should use the pipeline to help with this. Depending on how many variances you have something like a switch statement might be better which is covered below.
$supplyFilter = 'DisplayName -like "*Supply*" -or DisplayName -like "*Supplies*"'
$accountFilter = 'DisplayName -like "*Accounting*" -or DisplayName -like "*Accountant*"'
Get-ADUser -SearchBase $OU -Filter $supplyFilter -Properties displayName | Move-ADObject -TargetPath $Test1OU
Get-ADUser -SearchBase $OU -Filter $accountFilter -Properties displayName | Move-ADObject -TargetPath $Test2OU
You could get freaky with this and make a custom object in a loop with filter and target pairs so that you don't need to repeat the cmdlet call to each Get-ADuser instance.
$moves = #(
#{
Filter = 'DisplayName -like "*Supply*" -or DisplayName -like "*Supplies*"'
OU = "OU=Test1, OU=Test, OU=Com"
},
#{
Filter = 'DisplayName -like "*Accounting*" -or DisplayName -like "*Accountant*"'
OU = "OU=Test2, OU=Test, OU=Com"
}
) | ForEach-Object{New-Object -TypeName PSCustomObject -Property $_}
ForEach($move in $moves){
Get-ADUser -SearchBase $OU -Filter $move.Filter -Properties displayName | Move-ADObject -TargetPath $move.OU
}
You should be able to scale into this easily by adding new $moves. This would be cleaner with PowerShell v3.0 but I do not know what version you have.
Using a switch
If you want something closer to what your currently have I would suggest something like this instead then.
$Users = Get-ADUser -SearchBase $OU -Filter * -Properties DisplayName
ForEach ($user in $users){
switch($user.DisplayName) {
($_ -like "*Supply*" -or $_ -like "*Supplies*"){Move-ADObject -Identity $user -TargetPath $Test1OU}
($_ -like "*Accounting*" -or $_ -like "*Accountant*"){Move-ADObject -Identity $user -TargetPath $Test1OU}
}
}

I'm not able to test currently, but this should do the trick:
Import-Module ActiveDirectory
$OU = "OU=Test, OU=com"
$Test1OU = "OU=Test1, OU=Test, OU=Com"
$Test2OU = "OU=Test2, OU=Test, OU=Com"
$users = (Get-ADUser -SearchBase $OU -Filter * -Properties displayName)
foreach ($user in $users)
{
if ($($user.displayName) -like "*Supply*" -OR $($user.displayName) -like "*Supplies*")){
Move-ADObject -Identity $user -TargetPath $Test1OU
}
elseif ($($user.displayName) -like "*Accounting*" -OR $($user.displayName) -like "*Accountant*")) {
Move-AdObject -Identity $user -TargetPath $Test2OU
}
}
I've Added an Identity Parameter to Move-ADObject also i've changed some of the var names to better reflect their content.

Related

Powershell - Ad user from OU to Security groups if not members of several groups

I'm writing a script to check if user from specific OU are not members of Group 1 or Group 2 or Group 3 or Group 4.
I have try this but some users are getting listed while they are not suppose to be.
get-aduser -filter * -searchbase "$Ou" | where-object {((get-aduser $_.samaccountname -properties memberof).memberof -ne "$grp1") -or ((get-aduser $_.samaccountname -properties memberof).memberof -ne "grp2") -or ((get-aduser $_.samaccountname -properties memberof).memberof -ne "grp3") -or ((get-aduser $_.samaccountname -properties memberof).memberof -ne "grp4")} | Select SamAccountName
Not sure I follow, but it sounds like you're asking for something like this:
$ou = 'OU=crowleytest,DC=contoso,DC=local'
$group1 = 'CN=group1,OU=crowleytest,DC=contoso,DC=local'
$group2 = 'CN=group2,OU=crowleytest,DC=contoso,DC=local'
$group3 = 'CN=group3,OU=crowleytest,DC=contoso,DC=local'
$group4 = 'CN=group4,OU=crowleytest,DC=contoso,DC=local'
$users = Get-ADUser -SearchBase $ou -Filter * -Properties memberof
$results = $users | where {
$_.memberof -notcontains $group1 -and
$_.memberof -notcontains $group2 -and
$_.memberof -notcontains $group3 -and
$_.memberof -notcontains $group4
}
$results
e - This filter could also be moved to the left into the -filter parameter for better performance, but that requires a different syntax. If you're not working with a huge list of users, the example above should suffice.

Can I not use a variable in with Get-ADUser

I have a variable I pull from a form that I need to tie in with a matching display name to retrieve an existing samAccountName.
If (Get-ADUser -Filter { (displayName -eq $user) -AND ($Returner -eq "Yes")} ) {
$Check = Get-ADUser -Filter{displayName -eq $user} -Properties SamAccountName
$sam = $check.SamAccountName
$sam
}
As soon as I have the -AND ($Returner.....) part in there the check fails to execute.
I need that check in there as that is what is passed from the Cherwell form to flag that a user is a returner and then I am going to pull in the current samAccountName for that person.
Can someone assist on how I should be using a check of a parameter in with the Get-ADUser command.
Many thanks
S.
I don't see why you would perform the same Get-ADUser command twice..
You can do this like below:
$adUser = Get-ADUser -Filter "DisplayName -eq '$user'" -Properties DisplayName, SamAccountName
$sam = if (($adUser) -and $Returner -eq "Yes" ) { $adUser.SamAccountName }
$sam
Hope that helps
You are using $Returner inside of the -filter of get-aduser. If I understand correctly, this is a variable created by a form.
You should check for $Returner inside of the if statement:
If ( (Get-ADUser -Filter { displayName -eq $user}) -AND ($Returner -eq "Yes")) {
$Check = Get-ADUser -Filter{displayName -eq $user} -Properties SamAccountName
$sam = $check.SamAccountName
$sam
}

Find security and distribution groups with owners whose account is disabled

I'm looking for some guidance on creating a powershell script that will check security and distribution groups from specific OU's and see if the owner is a user who's disabled.
We have lots of old groups in our AD created by ex employees that need to be cleaned up.
This is what i've started with.
$managedByGroups = get-adgroup -filter 'groupCategory -eq "Distribution"' -SearchBase "OU=SydExchangeGroups,OU=SydGroups,OU=Sydney,DC=my,DC=org,DC=biz" -Properties distinguishedname, managedby | select sAMAccountName, managedby
$disabledUsers = Get-ADUser -Filter {Enabled -eq $false} -SearchBase "OU=SydDisabledUsers,OU=SydMisc,OU=Sydney,DC=my,DC=org,DC=biz" | select distinguishedname
foreach ($group in $managedByGroups){
if($managedByGroups.managedby -eq $disabledUsers.distinguishedname)
{
write-output
}
}
Thanks
There are a number of issues with your if block:
you are looping through $managedByGroups, but you are never using that variable (it should be $group.managedby)
you are trying to compare 1 element with a list of elements, in this case consider using -in operator instead of -eq.
you should treat the case when there is no value for managedby attribute, in case you do not get the desired results.
An alternative to your code may is below.
I'm first getting the list of managedby users, then i'm looping though each entry, and if it is not null, we try to do a get-aduser filtering by enabled status and the distinguishedname.
$DisabledManagedBy variable will contains ADUser objects which are disabled.
$grp = get-adgroup -filter 'groupCategory -eq "Distribution"' -Properties ManagedBy,DistinguishedName
$DisabledManagedBy = foreach ($item in $grp.ManagedBy) {
if ($item) {
Get-ADUser -Filter {Enabled -eq $false -and DistinguishedName -like $item} -Properties DistinguishedName
}
}
I worked this out eventually by doing the following:
$myDisabledUsers = #()
$date = get-date -format dd-MM-yyyy
$managedSydGroups = Get-ADGroup -Filter * -Properties * -Searchbase "OU=SydExchangeGroups,OU=SydGroups,OU=Sydney,DC=my,DC=biz,DC=org" | where {$_.managedby -ne $null} | select name, managedby
$disabledSydUser = Get-ADUser -Filter * -SearchBase "OU=SydDisabledUsers,OU=SydMisc,OU=Sydney,DC=my,DC=biz,DC=org" | where {$_.enabled -eq $false} | select -ExpandProperty distinguishedname
$disabledOwners = foreach($group in $managedSydGroups)
{
$managedByString = [string]$group.managedby
if($disabledSydUser -contains $managedByString)
{$myDisabledUsers += $group}
}

Grab Managers from AD

I'm currently getting a list of managers in AD from
Get-ADUser -Filter "DirectReports -like '*'" -Properties *
Whats the easiest way to scan this against the entire AD domain to see if they are a manager?
Not working code:
$Users = Get-ADUser -Filter * -Properties *
Foreach ($User in $Users) {
If (Get-AdUser -Identity $User -Filter "DirectReports -like '*' -eq $True")
{Write-Host "$User is a Manager"} Else {Write-Host "$User is NOT a Manager"}
}
Thanks
Do you mean this?
Get-ADUser -Filter * -Properties directReports | ForEach-Object {
$isManager = ($_.directReports | Measure-Object).Count -gt 0
$_ | Select-Object name,
#{Name = "Manager"; Expression = {$isManager}}
}

Custom Object multiple lines

I created a script to pull some info from AD, the problem I'm having is the Secondary SMTP address field has more then one line. I'd like to show each secondary SMTP in a new line. My Script output looks like {smtp:joe.rodriguez#con...
$searchBase = 'OU=Users,DC=Contoso,DC=LOCAL'
$users = Get-ADUser -filter 'enabled -eq $true' -SearchBase $searchBase |select -expand samaccountname
Foreach ($user in $users){
$Secondary = get-recipient -Identity $user -ErrorAction SilentlyContinue| select Name -ExpandProperty emailaddresses |? {$_.Prefix -like "SMTP" -and $_.IsPrimaryAddress -like "False"} |select -ExpandProperty $_.Smtpaddress
New-Object -TypeName PSCustomObject -Property #{
Name = Get-ADUser -Identity $user -Properties DisplayName |select -ExpandProperty DisplayName
"Login ID" = Get-ADUser -Identity $user -Properties SamAccountName |select -ExpandProperty SamAccountName
Primary = get-recipient -Identity $user -ErrorAction SilentlyContinue| select Name -ExpandProperty emailaddresses |? {$_.Prefix -like "SMTP" -and $_.IsPrimaryAddress -like "True"} |select -ExpandProperty Smtpaddress
Secondary = $Secondary
}
}
Personally I'd make an array, pull your user list, and then iterate through the secondary SMTP addresses for each user adding your custom object to the array for each entry.
$Userlist = #()
$searchBase = 'OU=Users,DC=Contoso,DC=LOCAL'
$users = Get-ADUser -filter 'enabled -eq $true' -SearchBase $searchBase -Properties DisplayName
Foreach ($user in $users){
$Recip = get-recipient -Identity $user.samaccountname -ErrorAction SilentlyContinue| select Name -ExpandProperty emailaddresses |? {$_.Prefix -like "SMTP"}
$Recip|? {$_.IsPrimaryAddress -like "False"} |select -ExpandProperty Smtpaddress |%{
$UserList += New-Object -TypeName PSCustomObject -Property #{
Name = $User.DisplayName
"Login ID" = $User.SamAccountName
Primary = $Recip|? {$_.IsPrimaryAddress -like "True"} |select -ExpandProperty Smtpaddress
Secondary = $_
}
}
}
This script (based off your script above) also reduces the number of server queries by 3 per user I think, so it should run a ton faster.