Forum Discussion
Powershell help - export to CSV not working - exporting EXE version number - help required...
Hi, Gary.
There's at least three different ways you can retrieve file remote file information:
- WinRM;
- SMB
- WMI.
I'll cover the first two with examples. WMI shares the benefits of WinRM but I don't use WMI much these days, so I'm skipping it.
WinRM
Windows Remote Management has been around since about Vista/Server 2008, meaning it's very well established. That said, many people can't be bothered enabling it for remote connections and even fewer configure it to run securely over TLS. (The best and easiest way to enable WinRM for remote connections in a domain environment is via Group Policy, but that's beyond the scope of this discussion.)
So, you may or may not be well-positioned to leverage WinRM.
This example leverages Invoke-Command, which is far more efficient than using a foreach statement since Invoke-Command can process multiple computers in parallel (i.e. asynchronously), while foreach cannot (it processes one after the other, or "synchronously" - and I'm deliberately focusing on Windows PowerShell here, as it ships "out of the box", where PowerShell does not).
Example
This version would run over when using a non-TLS WinRM endpoint.
$ExportPath = "D:\Data\Temp\forum\fileInfo.csv";
Invoke-Command -ComputerName (Get-Content -Path "D:\Data\temp\forum\forum.txt") -ScriptBlock {
Get-Item -Path "C:\Data\SteamSetup.exe" -ErrorAction:SilentlyContinue |
ForEach-Object {
[PSCustomObject] @{
FileName = $_.VersionInfo.FileName;
Version = $_.VersionInfo.FileVersion;
}
}
} |
Select-Object -Property PSComputerName, Version, FileName |
Export-Csv -Path $ExportPath -NoTypeInformation;
Output
SMB
SMB is best known as "file and print", which is the approach you've taken in your initial example.
SMB is almost always enabled and accessible by default, and is positively ancient - it's been around in Windows NT since inception, which puts it around the early 1990's (though there have been multiple major revisions and it's still a very useful protocol).
The downside to the SMB approach is that it's most commonly going to be handled synchronously via a foreach statement. You can put extra effort into the coding to adopt an asynchronous approach, but most people go for easy ahead of efficient, meaning that rarely happens.
Because each computer is processed one at a time, this method is becomes more inefficient as more clients are unreachable for whatever reason.
Example
$ExportPath = "D:\Data\Temp\forum\fileInfo.csv";
Get-Content -Path "D:\Data\temp\forum\forum.txt" |
ForEach-Object {
Get-Item -Path "\\$_\c$\\Data\SteamSetup.exe" -ErrorAction:SilentlyContinue |
ForEach-Object {
[PSCustomObject] @{
FileName = $_.VersionInfo.FileName;
Version = $_.VersionInfo.FileVersion;
}
}
} |
Select-Object -Property Version, FileName |
Export-Csv -Path $ExportPath -NoTypeInformation;
Output
WMI
As mentioned, WMI is much the same as WinRM where the primary benefit is that is can process multiple computers at once via the Get-CimInstance commandlet, which - like Invoke-Command - can take multiple computer names in the -ComputerName parameter.
So, like the WinRM approach, it scales better when checking large numbers of computers.
Cheers,
Lain
- gower666Jul 03, 2024Copper Contributor
LainRobertson wow that was quick, thank you so much, that worked like a charm (2nd script). Thank you so so much, have a lovey day 🙂