Powershell Select-Object like two value - powershell

first time posting here.
I'm stuck with what i thought would be a simple task, trying to list Computers in AD with one or another Membership.
I just want to look in my #Ring variable for two strings as such as 'UPGRADE' or 'RING_'
Is there a simple way to do this ?
Thanks,
For now my code is like that
Get-ADComputer -SearchBase $Base_recherche -Properties * -Filter * |
Select-Object #{name="Nom machine";expression={$_.Name}},
#{n="Dernière date de connexion";e={$_.LastLogonDate}},
#{n="Systeme exploitation";expression={$_.OperatingSystem}},
#{n="Version";expression={$_.OperatingSystemVersion}},
#{n="CheminAD";expression={$_.CanonicalName}},
#{n="Ring";e={$_.memberof -like '*UPGRADE*'}} |
Export-CSV $Chemin_Export -Encoding UTF8 -NoTypeInformation

It seems if you need to only choose AD objects with a membership of 'UPGRADE' or 'RING_' you will need to use the -Filter parameter to filter out the objects ahead of time.
Get-ADComputer -SearchBase $Base_recherche -Properties * -Filter 'memberof -like '*UPGRADE*' -or memberof -like '*RING_*'
This will give you just the objects that satisfy the condition.
EDIT
You can combine the above code with your Select-Object but just add both elements you are looking for.
#{name="Ring";expression={$_.memberof -like '*Ring_*'}},
#{name="Upgrade";expression={$_.memberof -like '*UPGRADE*'}}
This will give you the two columns in your CSV with TRUE/FALSE values per computer line. This way you can know which systems belong to corresponding groups.
ComputerName,Ring,UPGRADE
machineA,true,false
machineb,true,true
machinec,false,true

Get-ADComputer by default returns objects with these properties:
DistinguishedName, DNSHostName, Enabled, Name, ObjectClass, ObjectGUID, SamAccountName, SID, UserPrincipalName
By writing -Properties * you're asking for ALL properties, which is wasteful and time consuming.
Better ask for the extra properties you DO need
Below joins the MemberOf DN's that have either 'UPGRADE' or 'RING_' with a semi-colon as Ring property in the output
$properties = 'LastLogonDate', 'OperatingSystem', 'OperatingSystemVersion', 'CanonicalName', 'MemberOf'
Get-ADComputer -SearchBase $Base_recherche -Properties $properties -Filter * |
Select-Object #{Name = "Nom machine"; Expression = {$_.Name}},
#{Name = "Dernière date de connexion"; Expression = {$_.LastLogonDate}},
#{Name = "Systeme exploitation"; Expression = {$_.OperatingSystem}},
#{Name = "Version"; Expression = {$_.OperatingSystemVersion}},
#{Name = "CheminAD"; Expression = {$_.CanonicalName}},
#{Name = "Ring"; Expression = {($_.MemberOf -match 'UPGRADE|RING_') -join '; '}} |
Export-CSV -Path $Chemin_Export -Encoding UTF8 -NoTypeInformation
If you want your Ring property to be just True if there is any MemberOf that has either 'UPGRADE' or 'RING_' found or False otherwise, then change this
#{Name = "Ring"; Expression = {($_.MemberOf -match 'UPGRADE|RING_') -join '; '}}
into
#{Name = "Ring"; Expression = {[bool]($_.MemberOf -match 'UPGRADE|RING_')}}

Related

Powershell sort-by numbers at end of values

I'm looking to sort numerically my output with the numbers at the end of each.
Get-ADComputer -Filter * -SearchBase "OU=ComputerOU,DC=dc,DC=com" -Properties * | Select-Object -ExpandProperty Name
What i would like:
QCL-00010
JPL-00011
TUL-00012
TUL-00013
QCL-00014
What i have:
JPL-00011
QCL-00010
QCL-00014
TUL-00012
TUL-00013
Thank you in advance
Using the example names, where all numeric values have the same length, padded with leading zeroes, you could simply extend the code you have:
Get-ADComputer -Filter * -SearchBase "OU=ComputerOU,DC=dc,DC=com" |
Select-Object -ExpandProperty Name |
Sort-Object {($_ -split '-')[-1]}
However, to be on the safe side I'd cast to [int] as well:
Get-ADComputer -Filter * -SearchBase "OU=ComputerOU,DC=dc,DC=com" |
Select-Object -ExpandProperty Name |
Sort-Object {[int]($_ -split '-')[-1]}
Result:
QCL-00010
JPL-00011
TUL-00012
TUL-00013
QCL-00014
BTW. if all you need is the .Name property, do not ask for ALL properties with -Properties *
If every computer in the OU matches the nomenclature, I would just use a calculated property with Sort-Object and some pretty standard text munging:
Get-ADComputer -Filter * -SearchBase "OU=ComputerOU,DC=dc,DC=com" |
Sort-Object -Property #{e={$_.Name.Substring($_.Name.IndexOf('-') + 1)}} |
Select-Object -ExpandProperty Name
Also, you should avoid -Properties * with Get-AD* commands unless you absolutely have to. Name is returned by default.
There are a couple of ways to do something like this, somewhat depending on how static the format is.
$Names = #(
'JPL-00011'
'QCL-00010'
'QCL-00014'
'TUL-00012'
'TUL-00013'
)
$Names | Sort-Object {[Void]($_ -match "(\d{5}$)"); $matches[1]}
Here I used the matches collection as the sort expression.

get all ADusers with numeric SamAccountName

How can I get all ADusers with numeric SamAccountName.
if SamAccountName include letter then I don't need it.
$num = Get-AdUser -Filter "SamAccountName -like [integer]" -Properties postalCode, postOfficeBox, SamAccountName, Enabled
With the -Filter you cannot test if a SamAccountName is made up of only digits and you will have to use the Where-Object clause for that using the regex -math operator.
$users = Get-AdUser -Filter * -Properties PostalCode, POBox, SamAccountName, Enabled |
Where-Object { $_.SamAccountName -match '^\d+$' }
Even though you cannot use -Filter to concisely complete your query, you can use -Filter to speed up your query times before piping to Where-Object:
$Params = #{ Properties = 'postalCode','postOfficeBox','SamAccountName','Enabled'
Filter = "samaccountname -like '" + (1,2,3,4,5,6,7,8,9,0 -join "*' -or samaccountname -like '") + "'"
}
Get-AdUser #Params | Where SamAccountName -match '^\d+$'
The idea is to only find objects with samaccountname beginning with a digit before sending to Where-Object, which will display only accounts that have all digits for the property value. This will significantly speed up the query times if you only have a small percentage of accounts that begin with a digit.

Run AD search for users not in Group excluding OU's

Good Afternoon
I am trying to create a PS script which pulls all users not in a certain Security group. I have managed to get this to work fine. However i require it to omit certain OU's as i don't want certain accounts included in this process like terminated users and support accounts for examples.
So i created the below to do this but it seems to fail. Its where i have tried to add some filtering. Can someone help put this in the right direction?
import-Module activedirectory
$results = #()
$users = Get-ADUser -Properties memberof -Filter {enabled -eq $true} | ? {$_.DistinguishedName -notlike "*,OU=Exchange,OU=Support Accounts,OU=Terminated Users and Computers do not use,OU=TerminatedEmployeesContractors,OU=TestAccounts*"} *
$ExportPath = 'c:\app\users_in_ou1.csv'
foreach ($user in $users) {
$groups = $user.memberof -join ';'
$results += New-Object psObject -Property #{'User'=$user.name;'Groups'= $groups}
}
$results | Where-Object { $_.groups -notmatch 'SG_XXXXXXXXXXX' } | Select-Object user | export-csv $ExportPath
Thanks
I would build a regex from all OUs that should be excluded from the search by joining the strings with the regex 'OR' character (|) and use the -notmatch operator.
Because there may be characters in these strings that have special meaning in regex, use [Regex]::Escape() on each before joining them.
Something like below:
Import-Module ActiveDirectory
# create a regex from an array of OUs to exclude by 'OR-ing' them with the pipe character
$excludeOUs = ('OU=Exchange','OU=Support Accounts','OU=Terminated Users and Computers do not use',
'OU=TerminatedEmployeesContractors','OU=TestAccounts' | ForEach-Object {[Regex]::Escape($_)}) -join '|'
$ExportPath = 'c:\app\users_in_ou1.csv'
# get a list of objects not having any of the excluded OUs in their DistinguishedName
# and at the same time output objects with properties 'User' and 'Groups'
$users = Get-ADUser -Properties Name, MemberOf -Filter 'Enabled -eq $true' |
Where-Object {$_.DistinguishedName -notmatch $excludeOUs} |
Select-Object #{Name = 'User'; Expression = {$_.Name}},
#{Name = 'Groups'; Expression = {($_.MemberOf -join ';')}}
# next filter this out further by excluding a certain group and export to Csv
$users | Where-Object { $_.Groups -notmatch 'SG_XXXXXXXXXXX' } | Export-Csv $ExportPath -NoTypeInformation

PowerShell- Get-ADUser Filter Issue

New to PowerShell and am having issues with Get-ADUser -Filter. I believe the issue has to do with the -Filter
$TC_TellerID_Array = #()
$TC_TellerID_Array = Import-Csv "C:\Designer.csv"
$ADUsersArray = #()
$ADUsersArray=get-aduser -filter * -Properties * | select Name, SamAccountName, extensionAttribute1, Enabled | where extensionAttribute1 -ne $null
Foreach ($User in $ADUsersArray)
{$TrimmedTeller = ($User.extensionAttribute1).Trim()
Foreach ($TC_TellerID in $TC_TellerID_Array)
{
Get-ADUser -Filter "'$TrimmedTeller' -eq '$TC_TellerID.TellerID'" -Properties * | Select Name,SamAccountName,extensionAttribute1, Enabled
}
}
Those single quotes are forcing a literal string. As #JosefZ pointed out. You would also want to pull your value of TellerID out using a SubExpression . Try changing your code to look like
Get-ADUser -Filter {$TrimmedTeller -eq $($TC_TellerID.TellerID)} -Properties * | Select Name,SamAccountName,extensionAttribute1, Enabled

powershell output of ad-user pwdLastSet and LastLoginTimeStamp

I'm working on a script that will run down a csv of LastName and FirstName of users on a domain and return someinfo about them in another csv.
Returning the properties is not an issue, but when I try to convert pwdLastSet and LastLogonTimeStamp to a readable format, it crashes when writing to the csv.
Here is my code. in this example, pwdLastSet will result in an unreadable 64bit number.
$names = import-csv C:\Users\me\Desktop\input.csv
$users = #()
foreach ($name in $names){
$filter = "givenName -like ""*$($name.FirstName)*"" -and sn -like ""$($name.LastName)"""
$users += get-aduser -filter $filter -Properties * | select-object employeeID, sn, givenName, distinguishedName, whencreated, passwordnotrequired, enabled, admincount, pwdlastset
}
$users | select employeeID, sn, givenName, distinguishedName, whencreated, passwordnotrequired, enabled, admincount, pwdlastset | export-csv c:\users\me\desktop\results.csv -NoTypeInformation
I'd like to throw $([datetime]::FromFileTime($user.pwdLastSet)) so it's readable in the output.
Any ideas?
You can use a calculated property to replace the value of a property or create an additional property:
$users += Get-ADUser -Filter $filter -Properties * |
select employeeID, ..., admincount,
#{n='pwdLastSet';e={[DateTime]::FromFileTime($_.pwdLastSet)}}
In this case it's an unnecessary step, though, because Get-ADUser already did that for you and placed that value in the PasswordLastSet property, as #user3815146 already pointed out (+1).
To get an overview of the properties of a user object you can use the Get-Member cmdlet:
Get-ADUser -Filter * -Property * | Get-Member
or list the members of any given user object:
Get-ADUser -Identity 'someuser' -Property * | Format-List *
On a more general note: never append to an array in a loop. The construct
$arr = #()
foreach ($item in $list) {
$arr += Do-StuffWith $item
}
guarantees poor performance, because with each iteration a new array is created (size + 1) and all elements are copied from the old array to the new one. Using a ForEach-Object loop in a pipeline provides far better performance:
$arr = $list | ForEach-Object { Do-StuffWith $_ }
Don't use pwdLastSet, try using PasswordLastSet.
On a different note, have you considered shortening your command to this:
$users += get-aduser -filter $filter -Properties employeeID,sn,givenName,distinguishedName, whencreated,passwordnotrequired,enabled,admincount,passwordlastset