Oxyauna
Oxyauna

Reputation: 75

Selecting single column where another is equal to a specific value

I have a CSV file with a list of servers in one column, and in the next column if the server is live, and in the third the server OS. I'd like to assign the names of the server to a variable where the OS is a Windows distro, however I only want the variable to store the server name.

$ServerList = "C:\Temp\ServerCompleteList.csv"
$Servers = Import-Csv -Path $ServerList
$LiveWindowsServerList = $Servers | select "Device Name"| where {($_.Status -eq "Live" -and $_.OS -like "*Windows*")}

Calling $LiveWindowsServerList returns no value. If I select the Status and OS as well, the variable shows the list correctly

$ServerList = "C:\Temp\ServerCompleteList.csv"
$Servers = Import-Csv -Path $ServerList
$LiveWindowsServerList = $Servers | select "Device Name","Status","OS"| where {($_.Status -eq "Live" -and $_.OS -like "*Windows*")}

Is it possible to store just the Server names in a variable if the Status is Live and the OS is Windows?

Upvotes: 0

Views: 642

Answers (1)

Doug Maurer
Doug Maurer

Reputation: 8868

The issue with your code is you are selecting a single property before filtering. This causes the filtering to fail because those properties don't exist. Let me show you

I'm providing some sample data for the sake of everyone.

@'
Device Name,Status,OS
Server1,Live,Windows Server 2019
Server2,Dead,Windows Server 2019
'@ | convertfrom-csv -OutVariable Servers

If you take just this portion of your code

$Servers | select "Device Name"

The result is a PSObject with a single property named 'Device Name'

$Servers | select "Device Name"

Device Name
-----------
Server1    
Server2    

Therefore filtering on $_.Status or $_.OS it will silently return nothing, because nothing matches and nothing errors.

$Servers | select "Device Name" | where {$_.Status -eq 'Live'} # No output

However, if you simply reverse the order.

$Servers | where {$_.Status -eq 'Live'} | select "Device Name" 

Device Name
-----------
Server1 

So if you change your code to

$ServerList = "C:\Temp\ServerCompleteList.csv"
$Servers = Import-Csv -Path $ServerList
$LiveWindowsServerList = $Servers | where {$_.Status -eq "Live" -and $_.OS -like "*Windows*"} | select "Device Name"

You should get the output you're expecting.

To further answer your question about storing just the server name in a variable, the fact of the matter is you already have it stored as a variable.

$servers.'Device Name'

Server1
Server2

Now that's a little awkward because the property contains a space. This may illustrate it more clearly.

$servers.OS

Windows Server 2019
Windows Server 2019

One more little note, if you are comparing a single property with Foreach, you can omit the braces like this.

$Servers | where OS -like *Windows* | select "Device Name"

Device Name
-----------
Server1    
Server2   

If you need to compare two or more properties, you can either use braces like you have or you can chain them together.

$Servers | where OS -like *Windows* | where status -eq Dead | select "Device Name"

Device Name
-----------
Server2   

You may also notice I did not use quotes on the words *windows* or Dead - from my understanding the reason is that arguments default to string type in powershell.

Upvotes: 1

Related Questions