Home > OS >  Powershell Conditional filter without regex
Powershell Conditional filter without regex

Time:09-20

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

  • Related