I am trying to create a line of code that will search for a specific user (from a list). My current code below is not working as it doesn't bring back anything when you run it. However, if I remove the whenCreated field it finds something. The user I am testing this with was created yesterday so not sure why it is not being returned. Any help always appreciated.
$startDate = (Get-Date).Date
$endDate = $startDate.AddDays(-30).Date
Get-ADUser -filter {Surname -eq $e -and physicalDeliveryOfficeName -eq $site -and whencreated -ge $enddate} | Select-Object samAccountName -ExpandProperty samAccountName
I would suggest to first get all users created on or after your $enddate and who'se Office property is equal to your variable $site and then eventualy filter those that can be found in your array if last names.
Also, -Filter should be a string, not a scriptblock.
Try
Get-ADUser -Filter "Office -eq '$site' -and Created -ge $enddate" -Properties Office, Created |
Where-Object { $yourListOfLastNames -contains $_.Surname }
If need be, you can pipe through to a Select-Object to obtain only the properties you need for your output.
By default, Get-ADUser outputs objects with these properties:
DistinguishedName, Enabled, GivenName, Name, ObjectClass, ObjectGUID, SamAccountName, SID, Surname, UserPrincipalName
and in this case we've extended that to also have Office (= physicalDeliveryOfficeName) and Created (= whenCreated converted to DateTime)
Related
So far I tried this**
Does not seem to work well, I get dates back from 2014.
And only a few from 2022
$90Days = (get-date).adddays(-90)
Get-ADUser -SearchBase "OU=Domain Users,DC=x,DC=state,DC=x,DC=x" -properties * -filter {(lastlogondate -notlike "*" -OR lastlogondate -le $90days) -AND (passwordlastset -le $90days)} | select-object name, SAMaccountname, lastlogondate | export-csv c:\Temp\90days.csv
It's a simple flip from less than to greater than. Dates are stored as numbers that increment every millisecond. Starting at a date 90 days ago and asking for "less than" means get everything from 90 days ago and earlier, not 90 days and greater to "today".
Simply flip your -le to -ge.
$90Days = (get-date).adddays(-90)
Get-ADUser -SearchBase "OU=Domain Users,DC=x,DC=state,DC=x,DC=x" -properties * -filter {(lastlogondate -notlike "*" -OR lastlogondate -ge $90days) -AND (passwordlastset -ge $90days)} | select-object name, SAMaccountname, lastlogondate | export-csv c:\Temp\90days.csv
Your filter is wrong. lastlogondate -notlike "*" -OR literally means if LastLogonDate not like anything OR ...
This means it would almost always pass the test.
Then, I don't see why you also include property PasswordLastset in the equation as your question is not about that.
I think this would work better for you:
$90Days = (Get-Date).AddDays(-90).Date # set the date to midnight
# to filter on enabled users only, you can also use the LDAPFilter parameter like:
# -LDAPFilter "(!(userAccountControl:1.2.840.113556.1.4.803:=2))"
Get-ADUser -Filter "Enabled -eq $true" -SearchBase "OU=Domain Users,DC=x,DC=state,DC=x,DC=x" -Properties LastLogonDate |
Where-Object {$_.LastLogonDate -ge $90Days} |
Select-Object Name, SamAccountName, LastLogonDate |
Export-CSV -Path 'c:\Temp\90days.csv' -NoTypeInformation
P.S. Don't ask for ALL properties with -Properties * if you only want one extra property on top of the attributes returned by default like Name and SamAccountName.
Note: Please also bear in mind that the calculated property LastLogonDate (not really an AD attribute at all) is not replicated within the domain and to get the most accurate value, you need to iterate the domaincontrollers in your domain.
I'm trying to sort my disabled users by the last date they logged in.
I used the following command:
Get-ADUser -Filter "samaccountname -eq '$user' -and enabled -eq '$False'" -Properties * |
select samaccountname, displayname, emailaddress, LastLogonDate |
Sort-Object -Property LastLogonDate
I'm not sure why, but it doesn't sort the LastLogonDate property. I keep getting an unsorted list of my disabled users.
Continuing from my comment, I think the code you show is the part inside a loop where you iterate users, perhaps based on the input from a CSV file.
Your code only finds one single user and sorts that one object on its LastLogonDate.
The sorting should be done after you have collected all your users like
# capture the resulting objects from a collection of users
$result = foreach ($user in $MyListOfUserSamAccountNames) {
Get-ADUser -Filter "samaccountname -eq '$user' -and enabled -eq '$False'" -Properties displayname, emailaddress, LastLogonDate |
Select-Object samaccountname, displayname, emailaddress, LastLogonDate
}
# here is where you sort the result for output
$result | Sort-Object -Property LastLogonDate
Please bear in mind that the calculated property LastLogonDate (not really a AD attribute at all) is not replicated within the domain and to get the most accurate value, you need to iterate the domaincontrollers in your domain.
I have a list of displaynames and I need to get their AD informations.
Get-Content "C:\displaynames.txt" |
foreach {
$givenname,$surname = $_ -split ' '
if (Get-ADUser -Filter "surname -eq '$surname' -and givenname -eq '$givenname'"){
Get-ADUser -Filter { displayName -match $_} -Properties EmailAddress, Manager | Select Givenname, Surname, SamAccountName, EmailAddress, Manager}
else {Get-ADUser -Filter { displayName -like "AD Test"} -Properties EmailAddress, Manager | Select Givenname, Surname, SamAccountName, EmailAddress, Manager}
} | Export-Csv -Path C:\result.csv
This works fine, but only if users have no middle names ex. John Moore
If the user has a middle name, it doesn't pick it up.
How can I change the script so it picks up users with middle names ex. John Roger Moore?
As Mathias R. Jessen already commented, you can use the -Filter on property DisplayName directly.
The Filter should be a string, not a scriptblock.
Using -Filter also has the advantage that you can suppress exceptions being thrown, so I would build in a step to confirm that we indeed did find a user with that displayname:
Get-Content "C:\displaynames.txt" | ForEach-Object {
$user = Get-ADUSer -Filter "DisplayName -eq '$_'" -Properties DisplayName, EmailAddress, Manager -ErrorAction SilentlyContinue
if ($user) {
# output the wanted properties as **object**
$user | Select-Object Givenname, Surname, SamAccountName, EmailAddress, Manager
}
else {
# nobody in this domain with a displayname like that..
Write-Warning "User '$_' could not be found.."
}
} | Export-Csv -Path 'C:\result.csv' -NoTypeInformation
Note that the Manager property is in the form of the managers DistinguishedName. If you want to get other properties for the manager, like his/her name, you will have to use Get-ADUser -Identity $user.Manager to get the wanted property there too
The basic question here is how to account for middle names.
PowerShell 5 has some AI-powered cmdlets.
Here, I will quote an example from the documentation.
Example 2: Simplify format of a string
$composers = #("Johann Sebastian Bach", "Wolfgang Amadeus Mozart", "Frederic Francois Chopin", "Johannes Brahms")
$composers | Convert-String -Example "first middle last=last, first"
Bach, Johann
Mozart, Wolfgang
Chopin, Frederic
Brahms, Johannes
The first command creates an array that contains first, middle and last names. Note that the last entry has no middle name.
The second command formats the names according to the example. It puts the last name first in the output, followed by the first name. All middle names removed; entry without middle name is handled correctly.
Convert-String (Microsoft.PowerShell.Utility) - PowerShell | Microsoft Docs
I've been scrambling around looking for examples of how -inputobject is used, and I cannot seem to find any. I've never touched powershell before, but when I recently started this job, and was told that this is a script we used, I couldn't help but start messing around with it! Pipes are fascinating, but I can't seem to get past this latest issue I have.
I have this huge list of data that comes out when looking up users in AD, and I was wondering if I could also snag the SamAccountName from the same code block!
$User = Get-ADUser -Filter "EmployeeID -eq '$NameID' -or SamAccountName -eq '$NameID' -or DisplayName -eq '$NameID' -or UserPrincipalName -eq '$NameID'" -Properties
Enabled,LockedOut,Mail,Created,passwordlastset,Description,PasswordExpired,LastLogonDate,EmployeeID,DisplayName,"msRTCSIP-UserEnabled",
"msDS-UserPasswordExpiryTimeComputed","extensionAttribute7",telephonenumber,targetaddress,distinguishedName |
Select-Object #{Expression={$_.Name};Label='User Name';},
#{Expression={$_.UserPrincipalName};Label='Logon Name';},
#{Expression={$_.DisplayName};Label='Display Name';},
#{Expression={$_.Created};Label='Date Created';},
#{Expression={$_.SamAccountName};Label='SamAccountName';} -InputObject $Name,
Description,
Enabled,
#{Expression={$_.LockedOut};Label='Locked';},
#{Expression={$_.Mail}; Label='Email Address';},
#{Expression={$_.passwordlastset};Label='PW Last Reset';},
#{Expression={[datetime]::FromFileTime($_."msDS-UserPasswordExpiryTimeComputed")};Label='Password Expiry';},
#{Expression={$_.LastLogonDate};Label='Last Logon';},
#{Expression={$_.PasswordExpired};Label='Password Expired';},
#{Expression={$_.extensionAttribute7};Label='Contract Expires On';},
#{Expression={$_.EmployeeID};Label='Employee ID';},
#{Expression={$_."msRTCSIP-UserEnabled"};Label='Skype Enabled';},
#{Expression={$_.telephonenumber};Label='Phone Number';},
#{Expression={$_.targetaddress};Label='Email Forwarded To';},
#{Expression={$_.distinguishedName};Label='Distinguished Name';} | Select-Object SamAccountName -InputObject $Name | Format-list | Out-String
The above is what I use to get most of the interesting information to display nicely in the script, but going forward, I have to call it again with my limited knowledge to simply input a user's SamAccountName into a $Name var(To gather their managers and the like.) It looks something like this:
$Name = (getad-user -Filter "EmployeeID -eq '$NameID' -or SamAccountName -eq '$NameID' -or DisplayName -eq '$NameID' -or UserPrincipalName -eq '$NameID'").SamAccountName
I was just wondering if I could compress it all down into one Get-ADUser, and what the best practice that would be!
Thanks in advance all
You have a pretty convoluted way to get what you want. To minimize the number of Get-ADUser calls just use a variable. You already assign a variable in the beginning but for whatever reason you "trash" the object.
Within your code Select-Object SamAccountName -InputObject $Name doesn't seem to make sense. You never show what you assign to $Name and with what you do before it, it look strange. As such I removed it in the below code.
$user = Get-ADUser -Filter "EmployeeID -eq '$NameID' -or SamAccountName -eq '$NameID' -or DisplayName -eq '$NameID' -or UserPrincipalName -eq '$NameID'" -Properties
Enabled,LockedOut,Mail,Created,passwordlastset,Description,PasswordExpired,LastLogonDate,EmployeeID,DisplayName,"msRTCSIP-UserEnabled",
"msDS-UserPasswordExpiryTimeComputed","extensionAttribute7",telephonenumber,targetaddress,distinguishedName
$niceDisplay = $user |
Select-Object #{Expression={$_.Name};Label='User Name';},
#{Expression={$_.UserPrincipalName};Label='Logon Name';},
#{Expression={$_.DisplayName};Label='Display Name';},
#{Expression={$_.Created};Label='Date Created';},
#{Expression={$_.SamAccountName};Label='SamAccountName';} -InputObject $Name,
Description,
Enabled,
#{Expression={$_.LockedOut};Label='Locked';},
#{Expression={$_.Mail}; Label='Email Address';},
#{Expression={$_.passwordlastset};Label='PW Last Reset';},
#{Expression={[datetime]::FromFileTime($_."msDS-UserPasswordExpiryTimeComputed")};Label='Password Expiry';},
#{Expression={$_.LastLogonDate};Label='Last Logon';},
#{Expression={$_.PasswordExpired};Label='Password Expired';},
#{Expression={$_.extensionAttribute7};Label='Contract Expires On';},
#{Expression={$_.EmployeeID};Label='Employee ID';},
#{Expression={$_."msRTCSIP-UserEnabled"};Label='Skype Enabled';},
#{Expression={$_.telephonenumber};Label='Phone Number';},
#{Expression={$_.targetaddress};Label='Email Forwarded To';},
#{Expression={$_.distinguishedName};Label='Distinguished Name';} | Format-list | Out-String
$name = $User.SamAccountName
The best practise would be to turn any piece of code into a resuable function and then combine multiple functions into modules. Since you are beginning with powershell you could start with a simple function like this:
Function Get-ADUserInfo {
param([string]$NameID)
Get-ADUser -Filter "SamAccountName -eq '$NameID'" -Properties Enabled,LockedOut,Mail,Created,passwordlastset,Description,PasswordExpired,LastLogonDate,EmployeeID,DisplayName,Manager,"msRTCSIP-UserEnabled","msDS-UserPasswordExpiryTimeComputed","extensionAttribute7",telephonenumber,targetaddress,distinguishedName |
Select-Object #{Expression={$_.Name};Label='User Name'},
SamAccountName
}
# call the function with different nameid values like so
$Name = Get-ADUserInfo -NameID someuser1
$Name = Get-ADUserInfo -NameID someuser2
managers info
Get-ADuser -Identity $Name.Manager
Inputobject as the name suggests is used to pass an object as an input to a function. The property samaccountname is already present in the output so there is no need to do anything else other than to just specify it as shown in the code above.
also why choose to display "Name" as "user name"? wouldn't it be easier to format the headers in excel?
Here are some links that could be helpful:
functions
https://learn.microsoft.com/en-us/powershell/module/microsoft.powershell.core/about/about_functions?view=powershell-5.1
Import-Module ActiveDirectory
Get-ADUser -SearchBase "OU=CompanySite,DC=example,DC=domain,DC=com" -filter {Enabled -eq $True -and PasswordNeverExpires -eq $False} -Properties "SamAccountName","msDS-UserPasswordExpiryTimeComputed", "Department", "Title", "Manager" |
Select-Object -Property "SamAccountName", #{Name="Password Expiry Date"; Expression={[datetime]::FromFileTime($_."msDS-UserPasswordExpiryTimeComputed")}}; #{Label="Manager";Expression={(Get-aduser -filter {sAMAccountName -eq $_.Manager}.sAMAaccountName)}};# |
Export-Csv "C:\Update\PasswordExpired.csv" -NoTypeInformation
I am trying to get an CSV that contains the employees whose password is expiring and get their managers name, the employees job title, the employees name and the date the password will expire.
However when I run this, I am getting the employees name and date the password is expiring. No other fields. I dont understand where I went wrong
Ok, there were a few errors causing issues:
You had a semi-colon (;) after the Password Expiry Date property in the Select-object portion. This caused the code to terminate at that point. It should be a comma.
For the Manager property, your expression is incorrect. You have your end parentheses after SamAccountName. It should be before the period. Additionally you are trying to match the DN with the SamAccountName data so it will return nothing. Just do a Get-ADUser and set the identity as the $_.Manager output. From there you can use the parentheses to output whatever metadata you want from the full ADUser Object for the manager. You can swap out SamAccountName to DisplayName or something else.
Your code: (Get-ADUser -filter {SamAccountName-eq $_.Manager}.SamAccountName)
Correct code: (Get-ADUser $_.Manager).SamAccountName
Title and Name are not included because you aren't calling them in the Select-object code. The "-Properties" section of Get-ADUser only adds the attribute to the list of retrieved attributes. What you set in Select is what is output to the screen or file.
You had a comment (#) tag before the Export-CSV section so that wasn't running either.
Here's the code. I don't have the manager attribute in my AD so I wasn't able to validate that section, but the rest ran correctly. I've also made it a bit more transportable. The SearchBase is now specified in a variable, as is the export location for the file. Additionally, you don't need to specify SamAccountName in the -Properties section as this is a default attribute for Get-ADUser.
Import-Module ActiveDirectory
$SearchPath = "OU=CompanySite,DC=example,DC=domain,DC=com"
$ExportPath = 'C:\Update\PasswordExpired.csv'
$Users = Get-ADUser -SearchBase $SearchPath -filter {Enabled -eq $True -and PasswordNeverExpires -eq $False} -Properties "msDS-UserPasswordExpiryTimeComputed", "Department", "Title", "Manager"
$Users | Select-Object -Property Name,"SamAccountName",Title,#{Name="Password Expiry Date"; Expression={[datetime]::FromFileTime($_."msDS-UserPasswordExpiryTimeComputed")}},#{Label="Manager";Expression={(Get-ADUser $_.Manager).sAMaccountName}} | Export-Csv $ExportPath -NoTypeInformation