First time poster but have been lurking for a while.
Anyway I stumbled upon this question and thought I should ask if there is quick way of solving this.
You would see for the status property:
Name: Status
MemberType: NoteProperty
Definition: Deserialized.System.ServiceProcess.ServiceControllerStatus Status=Stopped
Is there an easy/quick way of just getting either the deserialized or the string version of the definition?
I can always recreate new objects and just picking one of them in a foreach loop.
But is there a quicker way to “get rid” of one of the definition values for Status?
I think it has to do with the object being returned as a deserialized hash table. I had some issues access data that that object type in the past. I did some up with something similiar to what you are looking for, but it does have an extra step to make it into a hashtable that you can access.
$ret = Invoke-Command -computername comp1,comp2,comp3 -ScriptBlock {
New-Object PSObject -Property @{
Computer = hostname
IP = ipconfig
Pass_policy = net accounts
}
}
$hash = @{}
$ret | % {
$hash[$.computer]= $
}
You can then do something like $hash.‘computername’.ip and get the data.
Will give you an error because status gets two values named ‘value’ which don’t work.
I have solved the problem by creating new objects but I wonder if its possible to just get one of those values from the first invoke statement. Rather than go through an extra loop.
I ask because the native XML serialization/deserialization should work - the back-and-forth in JSON shouldn’t be necessary. In general, it’s considered a good practice to get the entire XML object and select locally…
So that the object being serialized isn’t a Selected subset. That just helps the ETS and formatting system make the right decisions. When you select remotely, you can indeed get some odd decisions being made, since the receiving computer doesn’t have a proper TypeName to match against. That’s when you’ll tend to get goofy hashtables.
Didn’t think of using the select after the return of the data, if it works then it would be a better solution.
Jonathan,
Sorry I tried to keep the “scenario” as close to the core problem as possible but I guess it became too short
I don’t want to convert the data straight away to json it was just a way to illustrate the problem.
Basically I’ve written a module that will inventory local and remote servers, according to our needs and then output the results to json.
Later on if we would like to use that information we could import the json file and convert it back to powershell objects or any other tool that can use json as a starting point.
Yes, doing the select after the invoked result, rather than in the scriptblock works.
Didn’t think it would be a difference but I guess I learn something every day
And consider persisting the results in CliXML. It’s a better-fidelity format; you can always use PowerShell to import that and convert to JSON if some other tool needs that.
Yeah, right. There’s only a few instances where you’d see that, but Services is one of those instances. The actual value is 4, but there’s a translation mechanism in play that also gives you “Running.” There’s some PowerShell magic getting involved in the middle. I can see where that would be troubling for strict JSON.
And for the record, that’s not happening because you’re selecting a subset of properties. It’d do it with the entire object, too. There are some other translated properties that’ll do the same thing, in fact, like StartType. But technically, Status becomes a collection, having two child objects. In really truly strict JSON, “value” and “Value” are different (case sensitivity). I think .NET’s JSON implementation is a little fuzzier, though.
The difference is that with CliXML, PowerShell will behave “more normally” after an import; if you use JSON as your persistence format, you’ll lose some of PowerShell’s automagic when you re-import. Hopefully not a deal-breaker for you.
Will have a look at the difference between CliXML and JSON.
One thing I noticed while doing the workaround by looping through the returned results was the selection of either the deserialized or the string value.
The code I used was:
While trying to select one of the values I experimented and I could get the string value with the above $status = $s.Status.Value example.
To get just the numerical value I found I could do $s.Status[0]
But $s.Status[1] didn’t result in the string value, maybe I’m missing something but it seemed a bit strange.
Anyway doing the select localy fixed the issue I was having.