4

I'm working with PowerShell to gather data from a list of remote servers which I then turn into a JSON object. Everything is working fine, but I get some really weird output that I can't seem to exclude.

I've tried piping the Invoke-Command results and excluding properties. I've also tried removing the items manually from the returned hash file, but I can't seem to make them go away.

What am I missing?

EDIT:

For the sake of figuring out what's wrong here is a simplified, but still broken, script:

$returnedServer = @{}
$pass = cat "C:\...\securestring.txt" | convertto-securestring
$mycred = new-object -typename System.Management.Automation.PSCredential -argumentlist "UserName",$pass
$s = @("xx.xxx.xxx.xxx","xx.xxx.xxx.xxx") 


foreach($server in $s)
{
    $returnedServer.$server += ,(Invoke-Command -ComputerName $server -ScriptBlock 
{
1
}-credential $mycred | select -ExcludeProperty PSComputerName,RunSpaceID,PSShowComputerName) 

$returnedServer| ConvertTo-Json

Which outputs:

{
"xx.xxx.xxx.xxx":  [
                       {
                           "value":  1,
                           "PSComputerName":  "xx.xxx.xxx.xxx",
                           "RunspaceId":  "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx",
                           "PSShowComputerName":  xxxx
                       }
                   ],
"xx.xxx.xxx.xxx":  [
                       {
                           "value":  1,
                           "PSComputerName":  "xx.xxx.xxx.xxx",
                           "RunspaceId":  "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx"",
                           "PSShowComputerName":  xxxx
                       }
                   ]
}
DiscOH
  • 177
  • 1
  • 7

4 Answers4

6

This post is really old, but I was unable to find an acceptable answer 6 years later, so I wrote my own.

$invokeCommandResults | ForEach-Object {
  $_.PSObject.Properties.Remove('PSComputerName')
  $_.PSObject.Properties.Remove('RunspaceId')
  $_.PSObject.Properties.Remove('PSShowComputerName')
}
John Homer
  • 266
  • 3
  • 3
2

You need to use Select-Object to limit the result to just the properties you want to show up in the JSON output:

$returnedServers.$server += ,(Invoke-Command -ComputerName $server -ScriptBlock 
{
...$serverHash = various look ups and calculations...
$serverHash
} | select PropertyA, PropertyB, ...)

For a more thorough answer you need to go into far more detail about your "various look ups and calculations" as well as the actual conversion to JSON.

Ansgar Wiechers
  • 193,178
  • 25
  • 254
  • 328
1

After some testing, it seems the problem is the object type. I was able to get your test script to work by explicitly casting the returned result.

$returnedServer = @{}
$pass = cat "C:\...\securestring.txt" | convertto-securestring
$mycred = new-object -typename System.Management.Automation.PSCredential -argumentlist "UserName",$pass
$s = @("xx.xxx.xxx.xxx","xx.xxx.xxx.xxx") 




foreach($server in $s)
{
  $returnedServer.$server += ,[int](Invoke-Command -ComputerName $server -ScriptBlock {1} -credential $mycred) 
}
$returnedServer| ConvertTo-Json
mjolinor
  • 66,130
  • 7
  • 114
  • 135
  • I'm either not integrating this solution correctly, or it doesn't work for this type of problem. I've updated the question to reflect this. – DiscOH Mar 13 '14 at 23:06
  • It's not you. I think it's because these are deserialized objects, and they're not behaving as expected. – mjolinor Mar 13 '14 at 23:54
-1

You could try this... instead of attempting to exclude extraneous property values, just be specific and "call" or "grab" the one(s) you want.

Quick Code Shortcut Tip! BTW, the Invoke-Command -Computer $server -Scriptbock {command} can be greatly simplified using: icm $server {command}

Now, getting back on track...

Using your original post/example, it appears that you are attempting to utilize one "value" by excluding all other values, i.e. -ExcludeProperty (which it is ultra-frustrating).

Let's start by removing and replacing the only exclusion section:

select -ExcludeProperty PSComputerName,RunSpaceID,PSShowComputerName

And instead, attempt to use one of the following:

1st Method: using the modified original command...

  $returnedServer.$server += ,(Invoke-Command -ComputerName $server -ScriptBlock {1}-credential $mycred).value 

2nd Method: using the "icm" version...

  $returnedServer.$server += ,(icm $server {1} -credential $mycred).value

Essentially, you are "picking out" the value(s) you need (vs. excluding property values, which is, again, pretty frustrating when it does NOT work).


Related Example(s) follows:

Here is a typical system Powershell/WMIC command call:

icm ServerNameGoesHere {Get-CimInstance -ClassName win32_operatingsystem}

But what if I only want the "version" from the object glob:

(icm ServerNameGoesHere {Get-CimInstance -ClassName win32_operatingsystem}).version

But, hold on, now I only want the "lastbootuptime" from the object glob:

(icm ServerNameGoesHere {Get-CimInstance -ClassName win32_operatingsystem}).lastbootuptime

Indecisively, I want to be more flexible:

$a=icm ServerNameGoesHere {Get-CimInstance -ClassName win32_operatingsystem}
$a.version
$a.lastbootuptime
$a.csname

(Makes sense?)

Good luck, ~PhilC