I have a list of 140 servers in a txt file and need to check status of Crowdstrike on each of them and then export to CSV. Would the below be correct?
$Computers = Get-Content -Path C:\temp\servers.txt
ForEach($Computer in $Computers){
Get-Service -Displayname "Crowdstrike Falcon Sensor Service"| select Status | export-csv c:\temp\results.csv -NoTypeInformation -Append
}
I have tried the above and resulted in error.
As Santiago points out, you're not using your iteration variable, $Computer
, in the loop body, so all Get-Service
calls are made locally.
In Windows PowerShell, select purpose-specific cmdlets such as Get-Service
themselves have a -ComputerName
parameter, so the following may work for you:
# Windows PowerShell only.
# If this doesn't work, see the Invoke-Command solution below.
Get-Service -Computer $Computers -Displayname 'Crowdstrike Falcon Sensor Service' |
Select-Object MachineName, Status |
Export-csv c:\temp\results.csv -NoTypeInformation
In PowerShell (Core) 7+, these cmdlet-individual -ComputerName
parameters are no longer supported, because they relied on the obsolete .NET Remoting APIs[1] that were removed from the modern, cross-platform .NET (Core) framework that underlies PowerShell (Core).
Now, only the general-purpose remoting cmdlets (Invoke-Command
, Enter-PSSession
) and the CIM cmdlets (e.g. Get-CimInstance
) have -ComputerName
parameters and use PowerShell's WinRM-based remoting, which is firewall-friendly.
Therefore - assuming the target servers are set up for PowerShell remoting - use the following (also works in Windows PowerShell):
Invoke-Command -ComputerName $Computers {
Get-Service -Displayname 'Crowdstrike Falcon Sensor Service'
} |
Select-Object MachineName, Status |
Export-csv c:\temp\results.csv -NoTypeInformation
Note:
Both solutions take advantage of the fact that -ComputerName
accepts an array of computer names, which not only shortens the code but allows the computers to be targeted in parallel.
The MachineName
property was added to the Select-Object
call in order to identify each originating computer in the output file.
The MachineName
property is a native member of the System.ServiceProcess.ServiceController
instances that Get-Service
emits, and, similarly, types output by other cmdlets that build on the obsolete .NET Remoting in Windows PowerShell, such as System.Diagnostics.Process
, as emitted by Get-Process
, have this property.
Independently, PowerShell remoting uses PowerShell's ETS (Extended Type System) to decorate all output objects with a PSComputerName
property (among others, see the bottom section of this answer), which allows identifying an output object's computer of origin irrespective of its type.
[1] If either endpoint was a non-.NET component, this form of remoting relied on DCOM - see the docs.