How to find properties of an object? - powershell

How can I find what properties object $a has in the following?
$a = 1
$a.length
$a | Get-Member
Get-Member does not seem to produce any properties for object $a? Is length a property of object $a?

$a is an Integer, it doesn't have a length property. Using Get-member is the right way to find object properties.

You can also pipe a sample object to Select-Object to see all properties and their values.
get-process | select -first 1 -prop *

Related

Possible to sort object by property (descending) and still display corresponding values?

$procs = Get-Process
$procs[0] | GM -MemberType Property
This gives all the properties in ascending order. Now, I'd like to display the properties in descending order but with it's values. It's easy to sort the properties themselves...
$procs[0] | GM -MemberType Property | Select-Object Name | Sort-Object -Descending -Property Name
...however this does not display the corresponding values.
I'm also able to sort values of one property in a descending manner but not sort by properties themselves.
EDIT: Here's a screenshot to better illustrate what I'd like to achieve:
What you can see here is the sample output of Get-Process | Where-Object { $_.Name -like "a*" } | Export-Csv -Path "$env:USERPROFILE\Desktop\example.csv"
As you can see the properties are not sorted. I would like to be able to output exactly what the screenshot shows but with the property columns and their corresponding values sorted in descending order, i.e. WS, VM, SI, PM, NPM, Name, Handles.
I hope I was able to clearly explain it now.
Thanks for your help.
It happens because, after all in your pipeline result is Hashtable with strings.
Save result in variable and give it into pipe like this,it's reveal each property in detail by putting Name of property after variable In "dot notation"
$propertys = (get-process)[0] | GM -MemberType Property | Select-Object Name | Sort-Object -Descending -Property Name
($propertys.NAME) | %{(get-process)[0].$_}
or use short presentation of properties by using FL
(get-process)[0] | fl $($propertys.Name[0..$propertys.Count])

Print only property names of PowerShell object

I'm trying to print out only the property names of a Powershell object.
In a script I do an Invoke-RestMethod and Write-Host ($response.result | Format-List | Out-String) gives me a nice list of the $response.result object.
Get-Member -InputObject $response.result also does not display what I want.
$response.result looks something like this: #{id=1; skip=true}.
How do I just get a list/table thats shows id, skip etc.
Many thanks!
All PowerShell objects have a hidden property PSObject that allows accessing information about the object, e.g. its properties:
$response.result.PSObject.Properties | Select-Object -Expand Name
If it's not a hashtable, you can use Get-Member to find the properties like this:
$response.result | Get-Member -MemberType Properties | Select-Object Name
If the result is just a simple 1-level hashtable, you could do something like:
(#{id=1; skip=$true}).GetEnumerator() | %{ $_.Key }
id
skip

Variablize Method Call in Powershell

I'm looking for a way to dynamically call a method or property of a function. For example say I wanted to call every property of $Error[0]. I could get a list of all the property names with:
$a = ($error[0] | get-member -type property | select Name)
I would then like to do something like this:
foreach($b in $a){
$error[0].&($b.Name)
}
But the call operator (&) doesn't resolve $b.Name like I would expect (it should resolve to 'CatagoryInfo'). Is there anyway to do something like this?
You could use different way to retrieve properties:
$Properties=$Error[0].PSObject.Properties
This will return collection of PSPropertyInfo objects. PSPropertyInfo objects have Value property which you could use to get or set property value:
$Properties|ForEach-Object {'Name={0}; Value={1}'-f$_.Name,$_.Value}
Also note of some possible problems in your way of retrieving properties' values. PowerShell allows you to access IDictionary elements with property syntax. Problem here is that PowerShell prefer to access to a collection element rather than actual property:
$Hashtable=#{}
$Hashtable.Count
# 0
$Hashtable.Add('SomeName',10)
$Hashtable.SomeName
# 10
$Hashtable.Count
# 1
$Hashtable.Add('Count',20)
$Hashtable.Count
# 20
$Hashtable|Select-Object -ExpandProperty Count
# 2
You can use Invoke-Expression:
$a = ($error[0] | get-member -type property | select Name)
foreach($b in $a){
Invoke-Expression "`$error[0].$($b.Name)"
}
Just remove the &
$a = ($error[0] | get-member -type property | select Name)
foreach($b in $a){
$error[0].($b.Name)
}

Powershell - When an object is placed on the pipeline, can it be used again later?

I have a collection of objects which I am trying to return multiple sets of data from. Each time I want to select one of the properties of the object and sort it uniquely.
The problem I'm getting is that I only get results the first time I use the collection. This leads me to wonder whether the objects are being "consumed" when I put them on the pipeline.
To illustrate with an example:
$results = getMyCollectionOfObjects
$results | select-object property1 | sort-object -unique property1
$results | select-object property2 | sort-object -unique property2
$results | select-object property3 | sort-object -unique property3
As far as I can tell this should result in 3 distinct lists of all the possible values for each of the three properties.
However for me it's like the $results value is being "used up" the first time it is selected from.
Is this the case and what should I do instead?
Hope this is clear.
That's how it rolls... you have to explicitly pipe them to Out-Default to get rid of that odd behavior. Otherwise it will try to display property1 for 2nd and 3rd set too. You removed it from $results, so it comes back blank.
HTH
Bartek
So this had me tripped up and scratching my head or a minute as well. The answer it turns out is really quite simple: the Select-Object cmdlet returns an object of type Selected.System.Management.Automation.PSCustomObject. That is then passed down the pipeline to following two selects, but since there are no longer any matching properties (they were discarded from the first select) - nothing is output. Consider the following example:
# declare an array and populate it
$results = #()
$results = $results + (New-Object PSobject -Property #{
P1 = "One"
P2 = "Two"
P3 = "Three"
})
$results = $results + (New-Object PSobject -Property #{
P1 = "Uno"
P2 = "Dos"
P3 = "Tres"
})
$results | select P1
$results | select P2
$results | select P3
As you described, I was only getting output from the first select. I them took the suggestion from BartekB to put | Out-Default at the end of each line and it started working. I investigated further by replacing that with | Get-Member to view the object the was being placed on the pipeline:
$results | select -Property P1 | get-member
TypeName: Selected.System.Management.Automation.PSCustomObject
Name MemberType Definition
---- ---------- ----------
Equals Method bool Equals(System.Object obj)
GetHashCode Method int GetHashCode()
GetType Method type GetType()
ToString Method string ToString()
P1 NoteProperty System.String P1=One
In a nutshell, the Out-Default is required to actually force it to display on the console instead of passing it along to the next statement. It would seem this behavior is implied upon completing a statement in the interactive shell, but behaves a bit differently when fully scripted.

PowerShell Format-List from different objects in the chain

How do I output properties from parent objects in a piped chain?
For example:
get-vm | get-vmdisk | forEach {Get-VHDInfo $_.DiskPath} | Select -Property Path, ParentPath, VM.VMElementName
Basically it's the VM.VMElementName that I'm wondering about (I made up that syntax). It's not the immediate object (which would be from Get-VHDInfo) but the grandparent (from get-vm) that I want to get a value for.
You cannot get values from upstream cmdlets the way you want to. You can use foreach-object right after calling get-vm and save the value in a variable, then assign it back to the select-object as a new calculated property.
get-vm | foreach-object{
$VMElementName = $_.VMElementName
get-vmdisk | forEach {Get-VHDInfo $_.DiskPath} | Select Path,ParentPath,#{Name='VMElementName';Expression={$VMElementName}}
}