Reputation: 75
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
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