I am trying to exclude an OU (sub-OU) from a search with PowerShell.
This is my code:
Get-ADOrganizationalUnit -filter * -SearchBase 'OU=test,DC=test,DC=com' |
foreach {
$users=Get-ADUser -filter * -searchbase $_.distinguishedname -ResultPageSize 2000 -resultSetSize 500 -searchscope Onelevel | where-object enabled -eq true
$total=($users | measure-object).count
New-Object psobject -Property #{
OU=$_.Name;
A=$Total
}
}
I'm a PowerShell beginner. Can you please help me to exclude an OU from the search results?
Thanks
By adding an if statement:
Get-ADOrganizationalUnit -filter * -SearchBase 'OU=test,DC=test,DC=com' | foreach {
if($_.distinguishedname -ne "OU=not,OU=that,OU=orgUnit,OU=test,DC=test,DC=com"){
$users=Get-ADUser -filter * -searchbase $_.distinguishedname -ResultPageSize 2000 -resultSetSize 500 -searchscope Onelevel | where-object enabled -eq true
$total=($users | measure-object).count
New-Object psobject -Property #{
OU=$_.Name;
A=$Total
}
}
}
Related
We are using a good script that we would like to extend to search for users everywhere except one OU. How can I do this?
Thanks in advance for your help!
PasswordChangeNotification
How to instert this code?
Get-ADOrganizationalUnit -filter * -SearchBase 'OU=test,DC=test,DC=com' | foreach {
if($_.distinguishedname -ne "OU=not,OU=that,OU=orgUnit,OU=test,DC=test,DC=com"){
$users=Get-ADUser -filter * -searchbase $_.distinguishedname -ResultPageSize 2000 -resultSetSize 500 -searchscope Onelevel | where-object enabled -eq true
$total=($users | measure-object).count
New-Object psobject -Property #{
OU=$_.Name;
A=$Total
}
}
}
On line 132 of the file you've linked to, you'll find the statement that actually queries Active Directory for the users:
$users = get-aduser -filter {(Enabled -eq $true) -and (PasswordNeverExpires -eq $false)} -properties Name, PasswordNeverExpires, PasswordExpired, PasswordLastSet, EmailAddress | where { $_.passwordexpired -eq $false }
Add the following statement to the next line:
$users = $users |Where-Object distinguishedname -notlike "*,OU=not,OU=that,OU=orgUnit,OU=test,DC=test,DC=com"
... and leave the rest of the script as-is
This script below works, but every attempt I make to have it cycle through all my domain controllers fail. How do I add a array to go through all these OUs on all my domain controllers. Thanks in advance!
$OUs= “OU=Test1,OU=Test1,OU=Test1,OU=Test1,OU=All Users,DC=domain,DC=local",
"OU=Test2,OU=Test2,OU=Test2,OU=All Users,OU=Test2,DC=domain,DC=local",
"OU=Test3,OU=Test3,OU=Test3,OU=All Users,OU=Test3,DC=domain,DC=local",
"OU=test4,OU=test4,OU=test4,OU=All Users,OU=test4,DC=domain,DC=local",
"OU=Test5,OU=test5,OU=Test5,OU=All Users,OU=test5,DC=domain,DC=local”
$OUs | ForEach-Object
{
Get-ADUser -Filter {Enabled -eq $TRUE} -SearchBase $_ -Properties Name,SamAccountName,LastLogonDate |
Where-Object {($_.LastLogonDate -lt (Get-Date).AddDays(-7)) -and ($_.LastLogonDate -ne $NULL)}
} |
Sort LastLogonDate |
Format-Table -Property Name,SamAccountName,LastLogonDate, DistinguishedName |
Out-String
Below you have now an array of your OUs. Please try whether that works for you now.
$OUs= #(
“OU=Test1,OU=Test1,OU=Test1,OU=Test1,OU=All Users,DC=domain,DC=local",
"OU=Test2,OU=Test2,OU=Test2,OU=All Users,OU=Test2,DC=domain,DC=local",
"OU=Test3,OU=Test3,OU=Test3,OU=All Users,OU=Test3,DC=domain,DC=local",
"OU=test4,OU=test4,OU=test4,OU=All Users,OU=test4,DC=domain,DC=local",
"OU=Test5,OU=test5,OU=Test5,OU=All Users,OU=test5,DC=domain,DC=local”
)
I would also suggest to break your line after every pipe in order to cut the line. That makes it far easier to read for you, plus your colleagues.
$OUs | ForEach-Object
{
Get-ADUser -Filter {Enabled -eq $TRUE} -SearchBase $_ -Properties Name,SamAccountName,LastLogonDate |
Where-Object {($_.LastLogonDate -lt (Get-Date).AddDays(-7)) -and ($_.LastLogonDate -ne $NULL)}
} |
Sort LastLogonDate |
Format-Table -Property Name,SamAccountName,LastLogonDate, DistinguishedName |
Out-String
You mention cycling through your domain controllers, but then you go on to ask about OUs. I suspect you want DC's, because each DC might have a different Last Logon Time for the user.
You can omit the -SearchBase and search all OU's, if you're looking to get this data for all users.
$Domains = Get-ADDomainController -Filter * #Note, this shows all DCs- you may have some without ADWS Installed, which won't handle the WHERE.
foreach ($domain in $Domains) {
Get-ADUser -Filter {Enabled -eq $TRUE} -Server $domain -Properties Name,SamAccountName,LastLogonDate |
Where {($_.LastLogonDate -lt (Get-Date).AddDays(-7)) -and ($_.LastLogonDate -ne $NULL)} |
Export-CSV -Path 'UsersNotRecentlyLoggedIn.CSV' -Append
}
If you only want one DC, but all OUs
$Domains = Get-ADDomainController -Discover -Service ADWS
foreach ($domain in $Domains) {
Get-ADUser -Filter {Enabled -eq $TRUE} -Server $domain -Properties Name,SamAccountName,LastLogonDate |
Where {($_.LastLogonDate -lt (Get-Date).AddDays(-7)) -and ($_.LastLogonDate -ne $NULL)} |
Export-CSV -Path 'UsersNotRecentlyLoggedIn.CSV' -Append
}
Need to export overall groups info in particular OU (recursively) from Acitve Directory structure with these fields:
OU | Groupname | GroupCategory | GroupScope | GroupMemberOf |
GroupMembers (other groups,not users) | TotalUsers (if any) |
UsersEnabled | Usersdisabled | UsersWithStalePass |
UsersWithNonexpirePass
all this info I need for each OU (Groups hierarchy,recursively).
I've found several examples and tried to consolidate'em, but I'm having several troubles in output. I've coded them below in comments.
This is the code for now:
#searchbase OU
$OU="OU=Groups,OU=OUNAME,DC=DCNAME2,DC=DCNAME,DC=domain"
$group = Get-ADGroup -filter * -Properties *
$allou = (Get-ADObject -Filter {ObjectClass -eq "organizationalUnit"} -SearchBase $OU).DistinguishedName
#list all sub OUs
Foreach($ou in $allou){
$LIST = Get-ADObject -LDAPFilter "(objectClass=group)" -SearchBase $OU -SearchScope OneLevel
#begin work with each OU
$LIST | ForEach-Object {
$users=Get-ADGroupMember $_.DistinguishedName | Where ObjectClass -eq "user"
$total=($users | measure-object).count #counts right
$Enabled=($users | where {$_.Enabled} | Measure-Object).count #always shows zero (0)
$Disabled=$total-$Enabled
$NonExpirePasses=(Get-ADUser -Identity $_.DistinguishedName | where {$_.PasswordNeverExpires -ne $true} | Measure-Object).count #doesn't work
#this variant won't work either: $NonExpirePasses=($users | where {$_.PasswordNeverExpires -ne $true} | Measure-Object).count
$PassesOver90d=($users | where {$_.PasswordLastSet -lt (Get-Date).AddDays(-10)} | Measure-Object).count #the same - always shows 0
#this variant won't work either: $PassesOver90d=(Get-ADUser $_.DistinguishedName | where {$_.PasswordLastSet -lt (Get-Date).AddDays(-90)} | Measure-Object).count
$GroupCategory=Get-ADGroup $_.DistinguishedName | Select-Object GroupCategory
$GroupScope=Get-ADGroup $_.DistinguishedName | Select-Object GroupScope
$InGroups=(($_.MemberOf | %{(Get-ADGroup $_).sAMAccountName}).count -join ";")
#consolidate info in new object
New-Object psobject -Property #{
OU=$OU;
GroupName=$_.Name;
GroupCategory=$GroupCategory;
GroupScope=$GroupScope; #<<<always gives "#{GroupCategory=Security}' or #{GroupCategory=Distribution} format, and i need simple 'Security'/'Distribution'
InGroups=$InGroups; #<<<always 0
TotalUsers=$Total;
Enabled=$Enabled; #<<<always 0
Disabled=$Disabled;
PassesOver90d=$PassesOver90d; #<<<always 0
NonExpirePasses=$NonExpirePasses} | #<<<even doesn't shown (no 0),no info
#sorted output, finish
Select OU,GroupName,GroupCategory,GroupScope,InGroups,TotalUsers,Enabled,Disabled,NonExpirePasses,PassesOver90d
}
}
This is the sample output (besides red mistakes with Identity in Get_ADUser commands):
OU : OU=SD,OU=Distribution Groups,OU=Groups,OU=OUNAME,DC=DCNAME2,DC=DCNAME,DC=domain
GroupName : BT23_USERS
GroupCategory : #{GroupCategory=Security}
GroupScope : #{GroupScope=Universal}
TotalUsers : 15
Enabled : 0
Disabled : 15
NonExpirePasses :
PassesOver90d : 0
Resulting info is gathered very slowly.How to optimize the code ?
Here's a version that seems to work:
$rootOU="OU=Groups,OU=OUNAME,DC=DCNAME2,DC=DCNAME,DC=domain"
$everyOU = (Get-ADObject -Filter {ObjectClass -eq "organizationalUnit"} -SearchBase $rootOU)
$everyOU | ForEach-Object {
Get-ADGroup -Filter {Name -like "*"} -SearchBase $_.DistinguishedName -SearchScope OneLevel -Properties * |
ForEach-Object {
$users = Get-ADGroupMember $_.DistinguishedName |
Where ObjectClass -eq "user" | ForEach-Object {Get-ADUser $_.SamAccountName -Property PasswordLastSet, PasswordNeverExpires}
$total = #($users).Count
$enabled = ($users | Where-Object Enabled -eq $true | Measure-Object).Count
$disabled = $total - $enabled
$NonExpirePasses = #($users | Where-Object PasswordNeverExpires -ne $true).Count
$PassesOver90d = #($users | Where-Object PasswordLastSet -lt (Get-Date).AddDays(-10)).Count
$GroupCategory = Get-ADGroup $_.DistinguishedName | Select-Object GroupCategory
$GroupScope = Get-ADGroup $_.DistinguishedName | Select-Object GroupScope
$InGroups = ($_.MemberOf).Count
[PsCustomObject]#{
OU=$_.DistinguishedName
GroupName=$_.Name
GroupCategory=$GroupCategory.GroupCategory
GroupScope=$GroupScope.GroupScope
InGroups=$InGroups
TotalUsers=$Total
Enabled=$Enabled
Disabled=$Disabled
PassesOver90d=$PassesOver90d
NonExpirePasses=$NonExpirePasses
}
}
} | Format-Table GroupName,GroupCategory,GroupScope,InGroups,TotalUsers,Enabled,Disabled,PassesOver90d,NonExpirePasses,OU -AutoSize
Fairly new to Powershell, I managed to get the following code to retrieve the Bitlocker key for computers in the domain, however, I have an issue with it:
Clear-Host
$TestOU = "OU=ABC,DC=XYZ,DC=com"
$PCs = Get-ADComputer -Filter * -SearchBase $TestOU
$Results = ForEach ($Computer in $PCs)
{
New-Object PSObject -Property #{
ComputerName = $Computer.Name
RecoveryPassword = Get-ADObject -Filter 'objectclass -eq "msFVE-
RecoveryInformation"' -SearchBase $computer.DistinguishedName -Properties
msFVE-RecoveryPassword,whencreated | sort whencreated -Descending | select
msfve-recoverypassword
}
}
$Results
My output for each password begins with {a{msfve-recoverypassword= and I'm not sure how to remove this.
The following code gives useful output for human consumption in the shell, but may also be used in a script:
$computer = Get-ADComputer $computerName
Get-ADObject -Filter 'objectClass -eq "msFVE-RecoveryInformation"' -SearchBase $computer.DistinguishedName -Properties whenCreated, msFVE-RecoveryPassword | `
Sort whenCreated -Descending | Select whenCreated, msFVE-RecoveryPassword
The I wrote the below script to return the name of all the Organisational Units in the domain that are empty.
I would like the script to also tell me the total number of empty OU's at the end, by counting the lines returned. I've tried assigning an $array to the New-Object, and adding various versions of $array.count or | Measure-Object at the end of the script, but all return 0.
Get-ADOrganizationalUnit -Filter * |
foreach {
$o = Get-ADObject -filter * -searchbase $_.distinguishedname -searchscope 1
$total = ($o | Measure-Object).Count
New-Object psobject -Property #{
Name=$_.distinguishedname
} |
where-object {$total -le "0"}
}
$ou = Get-ADOrganizationalUnit -Filter * |
Where-Object { -not (Get-ADObject -SearchBase $_.DistinguishedName -Filter * -SearchScope OneLevel) }
# get the count
$ou|measure
$list OUs
$ou