I was 'geekily' excited, when this occurred to me this AM.
Largely because I have been frustratedly looking for a way to deal with a limitation that PSExec presents, when I am trying to get information from a remote computer.
(More info on PSExec, which is part of the SysInternals suite, here)
When pointing a (PoSh) command at a remote computer via PSExec - Specifically one that returns a result that is an array - Capturing that returned result is not an array - It is a simple string, with multiple lines.
Parsing that returned string is certainly possible - But there are a few steps involve in parsing it.
It would be SO MUCH EASIER if that returned value was still an array... Right?!
Google searching for a way to do this... For YEARS - Has not provided anything on how to keep that array... an array...
This morning... I had a thought...
As it turns out - piping that array to 'ConvertTo-Csv' as part of the command being ran on the remote computer is the key!
Then capturing the returned CSV value and piping it to 'ConvertFrom-Csv' - and Ta-Da! It's an array!
Below is a simple example, and also a more involved sample.
In the more involved sample - I send an actual script to the remote computer and run that script.
There may be a better way to run a multiple line script via PSExec - I am not sure...
But the way I am doing it does make it much easier - If only that I don't have to 'escape' all of the quotes (") and dollar signs ($), with tilde marks (`) all over it (as seen in the simple example).
I certainly am open to suggestions...
(As always - Forgive me for using aliases for commands, that is just how I roll...)
NOTE: I have been in the habit of using this '.split()' for a while, on strings - Just to clean up 'array to string' situations, that invariably end up with leading and trailing spaces:
($Args).Split("`n|`r",[System.StringSplitOptions]::RemoveEmptyEntries)
$Computer_Name = "<hostname>" $DiskInfo = (C:\SysInternals\PsExec.exe -s -nobanner \\$Computer_Name /accepteula cmd /c powershell.exe ` "& { get-WmiObject win32_logicaldisk | ? {`$_.DeviceID -eq 'C:'} | Select FreeSpace, Size | ConvertTo-Csv }"` 2> $null) | ConvertFrom-Csv ######## A more involved example ######### $CMD = 'C:\SysInternals\PsExec.exe -s -nobanner \\$Computer_Name /accepteula cmd /c powershell.exe "& { $C_Line }" 2> $null' $RAM_Report = @' $DiskInfo = get-WmiObject win32_logicaldisk | ? {$_.DeviceID -eq 'C:'} | Select FreeSpace, Size Get-ComputerInfo | Select ` @{ N = 'Hostname'; E = { $_.CsDNSHostName } },` @{ N = 'Username'; E = { $_.CsUserName } },` @{ N = 'Last Boot'; E = { $_.OsLastBootUpTime } },` @{ N = 'RAM'; E = { "$([math]::round($_.CsPhyicallyInstalledMemory /1MB, 3)) GB" } },` @{ N = 'Free RAM'; E = { "$([math]::round($_.OsFreePhysicalMemory /1MB, 3)) GB" } },` @{ N = 'UpTime'; E = { "$($_.OsUptime.Days) Days(s), $($_.OsUptime.Hours) hour(s)" } },` @{ N = 'DiskSize'; E = { "$([Math]::Round($DiskInfo.Size / 1GB,2)) GB" } },` @{ N = 'FreeSpace'; E = { "$([Math]::Round($DiskInfo.FreeSpace / 1GB,2)) GB" } },` @{ N = '%Free'; E = { "$(([Math]::Round(($DiskInfo.FreeSpace) / ($DiskInfo.Size),3)) * 100)%" } } | ConvertTo-Csv '@ ######################################## $OutFilePath = "\\$Computer_Name\c$\Users\Public\Downloads\RAM_Report.txt" $RAM_Report | Out-File $OutFilePath -Force $C_Line = "iex ((New-Object System.Net.WebClient).DownloadString('C:\Users\Public\Downloads\RAM_Report.txt'))" $Remote_Info = (iex $CMD).Split("`n|`r",[System.StringSplitOptions]::RemoveEmptyEntries) | ConvertFrom-Csv
No comments:
Post a Comment