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
Related
I am trying to add members to a AD group based on a value in the "title" attribute. I have about 30 different tiles i want to use. Is there a way to write the command witout 30 "OR" statements?
Thanks
Get-ADuser -filter {(title -eq "SECSCH") -or (title -eq "SEC12") -or (title -eq
"LTOSEC") -or (title -eq "LTO12")} | %{Add-ADGroupMember "SDK test print color"
$_.SamAccountName}
Also, for another group I would like All "custod" in title except at location "85c" and "42c" Below is where i am at.
Get-ADuser -filter {(title -eq "custod") -and (locationNumber -ne "85c") -or (title -eq
"custod") -and (locationNumber -ne "42c")} | %{Add-ADGroupMember "SDK test print
convert" $_.SamAccountName}
For your first issue you can create an array which contains your titles and browse it.
Example :
$Titles = "SECSCH","SEC12","LTOSEC","LTO12"
foreach($Title in $Titles){
Get-ADuser -filter {title -eq $Title} | %{Add-ADGroupMember "SDK test print color" $_.SamAccountName}
}
The -Members parameter can take an array of ADPrincipal objects so what you can do instead of using so many 'OR's in the Filter is using a Where-Object clause afterwards.
This will allow you to use operators like -contains or -match
$titles = "SECSCH","SEC12","LTOSEC","LTO12" # your 30+ titles here
$users = Get-ADUser -Filter * -Properties Title | Where-Object { $titles -contains $_.Title }
Add-ADGroupMember -Identity "SDK test print color" -Members $users
As for your second code change the Filter to below
$filter = "Title -eq 'custod' -and (locationNumber -ne '85c' -and locationNumber -ne '42c')"
$users = Get-ADUser -Filter $filter -Properties Title, locationNumber
Add-ADGroupMember -Identity "SDK test print convert" -Members $users
Note: the property locationNumber is AFAIK not a standard attribute in AD. Is that a custom property in your organization or do you perhaps mean something else like Division or EmployeeNumber ?
I provided a different answer to the first at the other place it was asked, using -Ldapfilter, but I feel #Onyx's answer here is probably more intuitive if you're not so comfortable with that. It's efficient in that you're only getting the objects you need, not grabbing every account out of AD and throwing away most of them.
To be honest, doing -Filter 'title -like "*"' would be better than nothing if you MUST use a Where clause.
For the second question (as described in the comments), the same applies with maybe building an LDAPfilter or #Onyx's method of creating an array for your customlocations and doing a Foreach through those.
Or again, at the very least, do -Filter '(employeeType -ne "student") -and (CustomLocation -like "*")' before the Where.
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)
I'm trying to get AD users into a variable using multiple filters. However one of the filters has variables in it & I can't get it to work... I have searched for similar issues & tried applying those but nothing seems to work.
$FilterBase = "department"
$Filter = "IT"
$ADusers = Get-ADUser -ResultSetSize $null -SearchBase "OU=Users,DC=mydomain,DC=com" -Properties * -Filter {(Enabled -eq $True) -and ($FilterBase -like $Filter) -and (cn -notlike ""SMB_*"")} |
Select-Object distinguishedName |
Sort-Object distinguishedName
I'm trying to fill $ADusers with all enabled users whose commonname doesn't start with "SMB_" (don't ask) & where the department is IT. I used -like to prevent issues if the values in AD would have different casings (uppercase, lowercase, mixed case, ...).
The reason that I'm using variables for this is because in the end the script will be dynamic. At some point $FilterBase is going to be "company" instead of "department" and $Filter is going to be "HR" instead of "IT" etc...
But I just can't seem to get it to work:
Get-ADUser : Error parsing query: '(Enabled -eq $True) -and ($FilterBase -like $Filter) -and (cn -notlike ""SMB_*"")' Error Message: 'syntax error' at position: '74'.
At line:4 char:12
I have tried using quotes around the variables like "$Filter", "$($Filter)", ' $Filter ' but alas. And I know it's not best practice to use variables in Filter but I can't think of any other way to accomplish this.
Any suggestions?
the error has the key to the answer. I'm sure I'll find this again and use it myself because I look this up every year or so...
Error parsing query: '(Enabled -eq $True)...'
In this case the filter needs a simple string 'True' which the variable $True does equal.
Two options will work, either
Enabled -eq 'True'
or
Enabled -eq '$True'
but
Enabled -eq $True
will not.
This should work
Replaced the braces with double quotes so inside them the variables still parse
Put single quotes around all strings and variables that resolve into strings
'$True'
'$Filter'
'SMB_*'
$FilterBase = "department"
$Filter = "IT"
$ADusers = Get-ADUser -ResultSetSize $null -SearchBase "OU=Users,DC=mydomain,DC=com" -Properties CN -Filter "(Enabled -eq '$True') -and ('$FilterBase' -like '$Filter') -and (CN -notlike 'SMB_*')" |
Select-Object distinguishedName |
Sort-Object distinguishedName
Important to note the above syntax highlighting will make the sample above look wrong because it misses the tokens like $FilterBase and $Filter when there are inside single quotes inside double quotes. Remember that single quotes are just apostrophes when inside double quotes, therefore the tokens should be colored differently and not look like strings.
> "('$FilterBase' -like '$Filter')"
('department' -like 'IT')
Paste a sample like above and see what it resolves to - best way to figure it out.
its just simply syntax error.
$enabled = 'Enabled'
$EnabledTrueOrFalse = $true
$SN = 'Surname'
$surname = "Doe"
$OU = "OU=Users,DC=mydomain,DC=com"
Get-ADuser -filter{$enabled -eq $EnabledTrueOrFalse -and $SN -eq $surname} -SearchBase $OU -Properties * | Select-Object distinguishedName | Sort-Object distinguishedName
read more about it here
Thanks for the tips guys. I couldn't get it to work with multiple filters so I moved some filters to the where clause.
My current (working) code is now:
$FilterBase = "department"
$Filter = "IT"
$ADusers = Get-ADUser -ResultSetSize $null -SearchBase "OU=Users,DC=mydomain,DC=com" -Properties * -Filter "$FilterBase -like `"$Filter`"" |
Where {$_.Enabled -eq $True -and $_.CN -notlike "SMB_*"} |
Select-Object distinguishedName |
Sort-Object distinguishedName
I have found this script that filters me the passwprdexpirydate of enabled accounts on AD.
Get-ADUser -filter {Enabled -eq $True -and PasswordNeverExpires -eq $False} –Properties “DisplayName”, “msDS-UserPasswordExpiryTimeComputed” |
Select-Object -Property “Displayname”,#{Name=“ExpiryDate”;Expression{[datetime]::FromFileTime($_.“msDS-UserPasswordExpiryTimeComputed”)}}
It works fine but I would like to have it search just one specific AD account that I will type in. How do I accomplish that?
I would
This is one of those times where reading the documentation would answer your question, as the examples cover this question...
You can either replace the Filter for the Identity param:
Get-ADUser -Identity USERNAME
Or, update the filter:
Get-ADUser -Filter {Name -eq "USERNAME"}
Try something like this:
Get-ADUser -filter {Enabled -eq $True -and PasswordNeverExpires -eq $False} –
Properties "DisplayName", "msDS-UserPasswordExpiryTimeComputed" |
Select-Object -Property "Displayname",#{Name="ExpiryDate";Expression=
{[datetime]::FromFileTime($_."msDS-UserPasswordExpiryTimeComputed")}} |
Where-Object {$_.DisplayName -like "Username"}
I am attempting to create a power shell script that prompts input for specific AD groups that a particular org manages that will essentially filter out users that are no longer in the said org and ONLY returns the 'samaccountname' and current department for those particular users. I have started but it does not seem to filter correctly. Any advice would be greatly appreciated.
Add-Type -AssemblyName Microsoft.VisualBasic
$groupName = [Microsoft.VisualBasic.Interaction]::InputBox("Please enter AD group name to display users no longer in department:", "XYZ", "$env")
Get-ADGroupMember -Identity $groupName -Recursive | Get-ADUser -Properties Department -Filter {enabled -eq $true} | ? {$_.DistinguishedName -notlike "*,OU=XYZ,*"} | Select-Object SamAccountName,Department
It appears it doesn't like the -Filter you have for Get-ADUser, I think (not 100% on this) it is because coming through the pipeline, it is sending one user at a time, so there isn't anything to filter.
Here's what I would do/try (maybe a better way, but testing this seems to get where you want to go):
$MatchedUsers=#{}
$GroupMembers=Get-ADGroupMember -Identity $groupName -Recursive | Get-ADUser -Properties Department
ForEach ($User in $GroupMembers) {
If (($User.Enabled -eq "True") -and ($User.DistinguishedName -notlike "*,OU=XYZ,*")) {
$MatchedUsers=#{
'SamAccountName'=$User.SamAccountName
'Department'=$User.Department
}
$obj=New-Object -TypeName PSObject -Property $MatchedUsers
Write-Output $obj
}
}