I'm trying to get a list of Active Directory users who have no description set.
I start with getting a list of users:
$users = Get-AdUser -Filter {(Enabled -eq "True" )} -Properties Description
And then I tried these options (to get list of users with no description):
$NoDescrUsers = $users | Where-Object {$_.Description -eq ""}
$NoDescrUsers = $users | Where-Object {$_.Description -eq ''}
$NoDescrUsers = $users | Where-Object $_.Description -eq ""
$NoDescrUsers = $users | Where-Object {$_.Description -match ""}
$NoDescrUsers = $users | Where-Object -not {$_.Description -like '*'}
None of these work (or it returns 0 in a foreach or returns everyone). What should my command look like?
I'm not sure why none of the options you tried worked (it seems like they should). Having Googled the general consensus seems to be that you can do this successfully (and more efficiently) within the initial -filter. For example:
$NoDescrUsers = Get-AdUser -Filter {(Enabled -eq "True" ) -and (description -notlike '*')} -Properties Description
If you filter description -like or -notlike
'*'
) that means you'll take any character (or not).
If you want filter only empty description in your AD request, you could do:
$NoDescrUsers = Get-AdUser -Filter {(Enabled -eq "True" ) -Properties Description
if ($NoDescrUsers.Description -eq $null)
{write-host "no description"}
Related
I posted 4 days ago and the community have been really helpful! I can now look for users in a specific parent OU who have a last name.
My second step that I am trying to do is to now add those users who have a last name and are in the parent OU to a mail enabled security group. After some googling I found a piece of script that allows users to be added to such, but I need to edit to to specify my requirements. I thought I had tried to do this but it ended up still searching through the child OUs and adding those without a last name so I must have something wrong or jumbled.
My current script is
$Admin_Accounts = 'OU=Administrators,OU=Company,DC=CompanyDC,DC=local'
$Service_Accounts = 'OU=Administrators,OU=Company,DC=CompanyDC,DC=local'
$Disabled = 'OU=Administrators,OU=Company,DC=CompanyDC,DC=local'
$Test_PowerPoint_GPO = 'OU=Administrators,OU=Company,DC=CompanyDC,DC=local'
$Exclude = '({0}|{1}|{2})$' -f \[regex\]::Escape($Admin_Accounts), \[regex\]::Escape($Service_Accounts), \[regex\]::Escape($Disabled), \[regex\]::Escape($Test_PowerPoint_GPO)
Get-ADUser -Filter 'Enabled -eq $true' -SearchBase 'OU=Users,OU=Company,DC=CompanyDC,DC=local' |
Where-Object { !\[string\]::IsNullOrWhiteSpace($_.Surname) -and $_.DistinguishedName -notmatch $Exclude } |
Select-Object SamAccountName
$TargetGroup = “Company Team“
$TargetOU = “OU=Users,OU=Company,DC=Company,DC=local“
$Exclude = '({0}|{1}|{2})$' -f \[regex\]::Escape($Admin_Accounts), \[regex\]::Escape($Service_Accounts), \[regex\]::Escape($Disabled), \[regex\]::Escape($Test_PowerPoint_GPO)
$UserAccounts = Get-ADUser -Filter 'Enabled -eq $true' | ?{$_.DistinguishedName -like “_*$TargetOU*” -and $.Enabled -eq “True”}
Where-Object { !\[string\]::IsNullOrWhiteSpace($_.Surname) -and $_.DistinguishedName -notmatch $Exclude } |
Select-Object SamAccountName
ForEach($User in $UserAccounts)
{
$UsersName = $User.Name
\#Check for group membership
$Membership = Get-ADGroup $TargetGroup | Get-ADGroupMember | ?{$\_.Name -eq $UsersName}
if(!$Membership)
{
“Adding $UsersName to $TargetGroup”
Get-ADGroup $TargetGroup | Add-ADGroupMember -Members $User -Verbose
}
}
I tried to add pieces of script to specify my requirements
Seems to me your script is way more complex than it needs to be:
$Admin_Accounts = 'OU=Administrators,OU=Company,DC=CompanyDC,DC=local'
$Service_Accounts = 'OU=Administrators,OU=Company,DC=CompanyDC,DC=local'
$Disabled = 'OU=Administrators,OU=Company,DC=CompanyDC,DC=local'
$Test_PowerPoint_GPO = 'OU=Administrators,OU=Company,DC=CompanyDC,DC=local'
# Create regex matching list
[regex]$Exclude = "$Admin_Accounts|$Service_Accounts|$Disabled|$Test_PowerPoint_GPO"
$UserAccounts = Get-ADUser -Filter 'Enabled -eq $true' | Where-Object {
$_.DistinguishedName -like “_*$TargetOU*”
} | Where-Object {
![string]::IsNullOrWhiteSpace($_.Surname) -and $_.DistinguishedName -notmatch $Exclude
} | Select-Object SamAccountName
Apologies if this is a "Well, duh!" moment but I'm trying to figure out how to reference a prior calculated property in a script and I'm at a loss after searching various forums. The following script runs perfectly in my environment until the last line. The $theusers system array is pulled from a .csv
Get-MsolDevice -All -ReturnRegisteredOwners |
Where-Object {($_.DeviceOSType -eq 'iPhone' -or $_.DeviceOSType -eq 'iPad') -and $_.RegisteredOwners.Count -gt 0 -and $_.DeviceTrustLevel -eq 'compliant'} |
Select #{L='User';E={Get-ADUser -filter "UserPrincipalName -eq '$($_.RegisteredOwners -join(';'))'" -server "server.com" | Select -expandproperty name}},
#{L='EmailAddress';E={$_.RegisteredOwners -join(';')}},
#{L='Position';E={Get-ADUser -properties description -filter "UserPrincipalName -eq '$($_.RegisteredOwners -join(';'))'" -server "server.com" | Select -expandproperty description}},
#{L='Office';E={Get-ADUser -properties l -filter "UserPrincipalName -eq '$($_.RegisteredOwners -join(';'))'" -server "server.com" | Select -expandproperty l}},
#{L='DeviceName';E={$_.DisplayName}},
#{L='DeviceType';E={$_.DeviceOSType}},
#{L='DeviceOS';E={$_.DeviceOSVersion}},
#{L='LoginName';E={Get-ADUser -properties description -filter "UserPrincipalName -eq '$($_.RegisteredOwners -join(';'))'" -server "server.com" | Select -expandproperty samaccountname}},
#{L='TrueOffice';E={$theusers | where-object {$_.SamName -like $_.LoginName } | Select -expandproperty office }}
Everything works except the last line.
User : Doe, John Q.
EmailAddress : JDoe#server.com
Position : DAL.Court Jester
Office : Dallas
DeviceName : John’s iPad
DeviceType : IPad
DeviceOS : 13.3.1
LoginName : JDoe
TrueOffice :
I'm trying to use the "LoginName" created from the line above but it does not seem to be passed on as a variable.
I tried replacing $_.LoginName with the actual expression . . .
Get-ADUser -properties description -filter "UserPrincipalName -eq '$($_.RegisteredOwners -join(';'))'" -server "server.com" | Select -expandproperty samaccountname
. . . which created LoginName but still got blanks for TrueOffice.
On the last line, if I replace $_.LoginName with an actual login name, such as "JDoe", the "TrueOffice" information for "JDoe" is provided from $theusers, so I know the language is correct but I just can't figure out out to get LoginName to be recognized as a variable.
When $_.LoginName is changed to "JDoe"
User : Doe, John Q.
EmailAddress : JDoe#server.com
Position : DAL.Court Jester
Office : Dallas
DeviceName : John’s iPad
DeviceType : IPad
DeviceOS : 13.3.1
LoginName : JDoe
TrueOffice : North Texas
Thanks in advance for any insight into this.
I would avoid using Select-Object in this case and just use a foreach-object from which you cal Get-ADUser once and then return a custom PS object manually. I think the result is more flexible, readable and efficient:
Get-MsolDevice -All -ReturnRegisteredOwners |
Where-Object {($_.DeviceOSType -eq 'iPhone' -or $_.DeviceOSType -eq 'iPad') -and $_.RegisteredOwners.Count -gt 0 -and $_.DeviceTrustLevel -eq 'compliant'} | foreach {
$adUser = Get-ADUser -filter "UserPrincipalName -eq '$($_.RegisteredOwners -join(';'))'" -server "server.com"
[PSCustomObject] #{
'User"'= $adUser.name;
'EmailAddress' = $_.RegisteredOwners -join ';';
'Position' = $adUser.description;
# other properties omitted . . .
'LoginName' = $adUser.samaccountname
'TrueOffice' = $theusers | where-object {$_.SamName -like $adUser.samaccountname } | Select -expandproperty office
}
}
When you use $_.LoginName you are trying to access an output property which doesn't exist on the input object, $_. A workaround would be to wrap your Select in a ForEach-Object, inside of which you calculate and store in a variable the value on which both properties are based...
Get-MsolDevice -All -ReturnRegisteredOwners |
Where-Object {($_.DeviceOSType -eq 'iPhone' -or $_.DeviceOSType -eq 'iPad') -and $_.RegisteredOwners.Count -gt 0 -and $_.DeviceTrustLevel -eq 'compliant'} |
ForEach-Object -Process {
$emailAddress = $_.RegisteredOwners -join(';')
$user = Get-ADUser -filter "UserPrincipalName -eq '$emailAddress'" `
-server "server.com" -Properties 'Name', 'Description', 'l', 'SamAccountName'
$loginName = $user | Select -expandproperty samaccountname
$_ | Select #{L='User';E={$user.Name}},
#{L='EmailAddress';E={$emailAddress}},
#{L='Position';E={$user.Description}},
#{L='Office';E={$user.l}},
#{L='DeviceName';E={$_.DisplayName}},
#{L='DeviceType';E={$_.DeviceOSType}},
#{L='DeviceOS';E={$_.DeviceOSVersion}},
#{L='LoginName';E={$loginName}},
#{L='TrueOffice';E={$theusers | where-object {$_.SamName -like $loginName } | Select -expandproperty office }}
}
A few notes about the above code:
Instead of calling Get-ADUser once for each output property based on a user attribute, I retrieve the user object once with the exact properties that are needed.
The email address and login name are calculated once and stored in local variables for reuse.
There's not really any downside other than an imperceptible performance hit, but if you pass a pattern that doesn't contain any wildcard characters to -like (as in $_.SamName -like $loginName) you might as well use -eq.
If you really wanted to filter on partial string matches you could use $_.SamName -like "*$loginName*" or the case-sensitive $_.SamName.Contains($loginName) (but not -contains!).
I simplified usages like $user | Select -expandproperty name to $user.Name.
I'm trying to stitch together two lines of PowerShell, but I just can't figure the syntax. There is a post that sounds like it might be what I need, but it isn't using -LDAPFilter.
To generate a list of AD users created in the last 100 days, I use
$now = ((Get-Date).AddDays(-100)).Date
$users = Get-ADUser -Filter {whenCreated -ge $now} -Searchbase "OU=staff,OU=SMUC_Users,DC=stmarys,DC=ac,DC=ie" |
Where-Object { $_.Enabled -eq 'True' }
And this code from "How to get ALL AD user groups (recursively) with Powershell or other tools?" does the next step, which is to find all the groups that a user is a member of:
$username = 'd.trump'
$dn = (Get-ADUser $username).DistinguishedName
Get-ADGroup -LDAPFilter ("(member:1.2.840.113556.1.4.1941:={0})" -f $dn) |
select -Expand Name
but I can't pipe the output of the first into the second to get an overall list.
Get-ADUser -Filter {whenCreated -ge $now} -Searchbase "OU=staff,OU=SMUC_Users,DC=stmarys,DC=ac,DC=ie" |
Where-Object { $_.Enabled -eq 'True' } |
Select-Object DistinguishedName |
Get-ADGroup -LDAPFilter ("(member:1.2.840.113556.1.4.1941:={0})" -f $_) |
select -expand Name
The error message is:
Get-ADGroup : The search filter cannot be recognized
I thought the second code snippet extracted the distingushed name and supplied it to the filter, and that is what I have tried to do in the pipeline.
You are missing ForEach-Object (alias %).
The following code should work:
Get-ADUser -Filter {whenCreated -ge $now} -SearchBase "OU=staff,OU=SMUC_Users,DC=stmarys,DC=ac,DC=ie" `
| Where-Object { $_.Enabled -eq 'True' } `
| %{Get-ADGroup -LDAPFilter ("(member:1.2.840.113556.1.4.1941:={0})" -f $_.DistinguishedName)} `
| Select-Object -ExpandProperty Name
If you want to output both user and group information you can expand the code like this:
Get-ADUser -Filter {whenCreated -ge $now} -SearchBase "OU=staff,OU=SMUC_Users,DC=stmarys,DC=ac,DC=ie" `
| Where-Object { $_.Enabled -eq 'True' } `
| %{$group = Get-ADGroup -LDAPFilter ("(member:1.2.840.113556.1.4.1941:={0})" -f $_.DistinguishedName);Write-Output $_.UserPrincipalName $group.Name}
The script below works as is, I need to add the enabled -eq $true piece so I can audit the user list to see if they are also enabled (not just disabled). I have tried various ways and the scripted error out. Can anyone help?
$userID = Import-Csv "c:\users.csv"
foreach ($user in $userID) {
$employeeID = $user.employeeID
Get-ADUser -Filter {employeeID -eq $employeeID -and Enabled -eq $false} -Properties displayName,employeeID,mail,intelOwnerID,title,"msDS-UserPasswordExpiryTimeComputed","lastLogon" |
select "Displayname", "Enabled",
#{n="PasswordExpiryDate";e={[DateTime]::FromFileTime($_."msDS-UserPasswordExpiryTimeComputed")}},
#{n='LastLogon';e={[DateTime]::FromFileTime($_.lastLogon)}},
SamAccountName, employeeID, mail, intelOwnerID, title |
Export-Csv -Append "c:\temp\usersacct.csv"
To get both enabled and disabled users that are listed in your .csv you just need to stop filtering on Enabled -eq $false. Just change this line:
Get-ADUser -Filter {employeeID -eq $employeeID -and Enabled -eq $false} -Properties displayName,employeeID,mail,intelOwnerID,title,"msDS-UserPasswordExpiryTimeComputed","lastLogon" |
to
Get-ADUser -Filter {employeeID -eq $employeeID} -Properties displayName,employeeID,mail,intelOwnerID,title,"msDS-UserPasswordExpiryTimeComputed","lastLogon" |
I have limited, self-taught experience with PowerShell so this is probably something basic but I can't seem to get it right.
I'm in Active Directory and I need to pull a list of users who's email address doesn't start with their SamAccountName.
(So if your login is jdoe but your email is johndoe#mycompany.com then your profile would be returned)
I've got most of what I need...but I can't figure out how to compare the two properties against eachother.
Right now I have
Get-ADUser -Filter 'enabled -eq $true' -Properties *|
Where {$_.PasswordNeverExpires -eq $false} |
Select Name, SamAccountName, EmailAddress, PasswordNeverExpires
I've tried a few different things to filter what I need, the following command shows exactly what I want (but of course this syntax doesn't work)
Get-ADUser -Filter 'enabled -eq $true' -Properties *|
Where {$_.PasswordNeverExpires -eq $false} |
Where-Object EmailAddress -Contains SamAccountName |
Select Name, SamAccountName, EmailAddress, PasswordNeverExpires
Thanks!
Use a scriptblock for the Where-Object filter like in your second pipeline element:
Where-Object { $_.EmailAddress -notlike "$($_.SamAccountName)*" }
You can even combine it with the first filter, using the -and operator:
Where-Object { $_.PasswordNeverExpires -eq $false -and $_.EmailAddress -notlike "$($_.SamAccountName)*" }
Finally, specify only the properties you need rather that -Properties * (no need to wait for the Domain Controller to return data you won't need):
$Properties = 'Name','SamAccountName','EmailAddress','PasswordNeverExpires'
Get-ADUser -Filter 'enabled -eq $true' -Properties $Properties |Where-Object {
$_.PasswordNeverExpires -eq $false -and
$_.EmailAddress -notlike "$($_.SamAccountName)*"
} |Select-Object $Properties