Search code examples
powershellserveragentpowershell-remotingremoting

Powershell script to extract a list of servers/computers from a .txt file and then display status and then export to CSV?


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.


Solution

  • 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.

        • PowerShell remoting is enabled by default in server editions of Windows, starting with Windows Server 2012.
      • 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.

      • However, note that the order of output objects will typically not reflect the input order of computer names.
    • The MachineName property was added to the Select-Object call in order to identify each originating computer in the output file.


    [1] If either endpoint was a non-.NET component, this form of remoting relied on DCOM - see the docs.