Im trying to filter ADComputer by Name.
Our naming convention is a follows <CuntryCode>-<Location>-<DeviceType And Number>
we have diferent locations in both USA and MX, we also have serval type of devices
Example:
<Device Type>
Servers = S
Desktops = D
Laptops = L
Tablet = T
Routers = R
Switches = U
example of actual naming:
MX-BCN-D002 or US-TAM-L001
Im creating a Script that will look at a remote PC file system, and check if user has a local .PST file. I only want devices that are Type: Desktops and Laptops, but cant seem to create a condition to filter all other devce type
Partial Script:
$Enabled_PC_list =@()
$Enabled_Online_PC_List =@()
# $Enabled_Offline_PC_list =@()
$data = @()
$PCs = Get-ADComputer -filter "Enabled -eq '$true'" -SearchBase "DC=some,DC=domain" -properties name | Select-Object -ExpandProperty name
$Enabled_PC_list = $PCs
foreach($device in $Enabled_PC_list){
Write-Output ">>> testing Device: $device <<<"
if ($device -like "*-*-D*" -or $device -like "*-*-L*" ) {
if(Test-Connection -TargetName $device -Count 1 -Quiet){
$Enabled_Online_PC_List = $device
}
}else{
Write-Output "Device $device not valid "
}
}
}
So with this line if ($device -like "*-*-D*" -or $device.name -like "*-*-L*" )
i was hoping to filter out all devices that matched what im looking for and proceed to do a Test-Connection on those devices .
Do i need to use regex on this ?
How can i use regex in powershell?
Is there a better way ?
CodePudding user response:
You can do this better by letting Active Directory do the filtering for you, instead of filtering from your side. You can generate an LDAP Filter via string manipulation adding an LDAP Clause for each device type:
$filter = '(&(!userAccountControl:1.2.840.113556.1.4.803:=2)(|'
'S', 'D', 'L', 'T', 'R', 'U' | ForEach-Object {
$filter = '(name=*-*-{0}*)' -f $_
}
$filter = '))'
$onlinePCs = Get-ADComputer -LDAPFilter $filter -SearchBase "DC=some,DC=domain" | Where-Object {
Test-Connection -TargetName $_.DNSHostName -Count 1 -Quiet
}
The generated LDAP Filter would look like this (with some formatting):
(&
(!userAccountControl:1.2.840.113556.1.4.803:=2)
(|
(name=*-*-S*)
(name=*-*-D*)
(name=*-*-L*)
(name=*-*-T*)
(name=*-*-R*)
(name=*-*-U*)
)
)
And can be read as, all enabled objects (computers in this case because we're using Get-ADComputer
) which Name attribute is like *-*-S*
or *-*-D*
or *-*-L*
and so on.
CodePudding user response:
Reading though your replies, it got me thinking if LDAP can do the filtering, could powershsell do it to? so i tried this and it works
the where clause did the trick Where-Object {$_.Name -like "*-*-D*" -or $_.Name -like "*-*-L*" -or $_.Name -like "*-*-T*"}
$Enabled_Online_PC_List =[System.Collections.ArrayList]@()
$Enabled_Offline_PC_list =[System.Collections.ArrayList]@()
# $data = @()
$searchBase = "OU=USA,DC=some,DC=domain"
$Enabled_PC_list = Get-ADComputer -filter "Enabled -eq '$true'" -SearchBase $searchBase -properties name | Where-Object {$_.Name -like "*-*-D*" -or $_.Name -like "*-*-L*" -or $_.Name -like "*-*-T*"} | Select-Object -ExpandProperty name
foreach($device in $Enabled_PC_list){
# Write-Output "testing now $device"
if(Test-Connection -ComputerName $device -Count 1 -Quiet){
Write-Output " Now Adding $device to Enabled_Online_PC-List"
$Enabled_Online_PC_List.Add($device)
}else{
Write-Output " Now Adding $device to Enabled_Offline_PC_list"
$Enabled_Offline_PC_list.Add($device)
}
}
Write-Output $Enabled_Online_PC_List
so script is working time is cut off dramatically, now i ask again is there a better way? for some reason LDAP does not want to stick in my head