How do I get to the Get-Measure Count property value through piping without surrounding with parenthesises? (Powershell version 5)
I would like something like alias | measure | $_.Count.
TL;DR
Say I want to count the number of aliases in Powershell so I go
alias | measure | Select-Object -Property Count
Which returns a PSCustomObject and not the Int32 I was looking for.
Instead I can
alias | measure | foreach { $_.Count }
which relies on Get-Measure returning one and only one object. It works for this simple case but is IMO even then ugly.
Another working solution is to
( alias | measure ).Count
but I really don't like having to surround with parenthesises, especially when the alias|..|..|..|measure code gets long.
Finally I could
alias | measure | % { $_.Count }
which seems to be the best. But the {...} annoys me.
This latter version is the best so far.
To "extract" a single property from a custom object you can use -ExpandProperty like this:
Get-Alias |
Measure-Object |
Select-Object -ExpandProperty Count
Related
$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])
I have a collection of 4 variables as (Get-Variable | Where Name -Match "^astr.*"), array and text string variables mixed.
I'd like to see the type information of each of them for comparison reasons. If I type
$astr2.GetType() I get for BaseType 'System.Array'.
For
$astr3.GetType() I get 'System.Object', so I see the difference in their type.
However, so see all in one go via
Get-Variable | Where Name -Match "^astr.*" | Select {$_.GetType().BaseType}
I get 'System.Object' four times, but no different values.
Also
Get-Variable | Where Name -Match "^astr.*" | %{$_.GetType()}, or
Get-Variable | Where Name -Match "^astr.*" | %{$_.GetType().BaseType}
do not give the expected. Why is the iteration not working?
This works for me:
Get-Variable | Where Name -Match "^astr.*" | Select {$_.Value.GetType()}
Dank u wel, Gert-Jan and Jeroen! Adding ".Value" works as expected, and is totally backed by Jeroen's comment's first 13 words... Great help!
I'm trying to automate setting an IP address through PowerShell and I need to find out what my interfaceindex number is.
What I have worked out is this:
$x = ( Get-NetAdapter |
Select-Object -Property InterfceName,InterfaceIndex |
Select-Object -First 1 |
Select-Object -Property Interfaceindex ) | Out-String
This will output:
InterfaceIndex
--------------
3
Now the problem, when I try to grab only the number using:
$x.Trim.( '[^0-9]' )
it still leave the "InterfaceIndex" and the underscores. This causes the next part of my script to error because I just need the number.
Any suggestions?
This will get your job done:
( Get-NetAdapter | Select-Object -Property InterfceName,InterfaceIndex | Select-Object -First 1 | Select-Object -Property Interfaceindex).Interfaceindex
Actually you do not need two times to select the property: do like this:
( Get-NetAdapter |Select-Object -First 1| Select-Object -Property InterfceName,InterfaceIndex).Interfaceindex
Answering your immediate question: you can remove everything that isn't a number from a variable by, well, removing everything that isn't a number (or rather digit):
$x = $x -replace '\D'
However, a better aproach would be to simply not add what you want removed in the first place:
$x = Get-NetAdapter | Select-Object -First 1 -Expand InterfaceIndex
PowerShell cmdlets usually produce objects as output, so instead of mangling these objects into string form and cutting away excess material you normally just expand the value of the particular property you're interested in.
(Get-NetAdapter | select -f 1).Interfaceindex
No point in selecting properties as they are there by default. If you want to keep object do:
(Get-NetAdapter | select -f 1 -ov 'variablename').Interfaceindex
where f = first, ov = outvariable
$variablename.Interfaceindex
You don't need Out-String as cast to string is implicit when you output to screen. and if you try to work with this data further down powershell is clever enough to cast it from int to string and vice versa when needed.
I have script which retrieves data from a web service in XML format. Certain elements can be there - or not - and can contain one or more sub elements. Therfore I retrieve the value with this:
$uid = $changeRecord.newAttrs | Where{$_.name -eq 'uid'} | Select -ExpandProperty Values | select -Index 0
This works fine. Mostly there is only one sub element in the <values> part of the answer and even if not, I am only interested in the first one. However, the last part | select -Index 0 produces silent warnings into the Windows Event Log (see also here ) if there is only one element within <values>. Therefore I would like to get rid of the error.
So I am looking for a way to achieve the same behaviour without it throwings errors - and possible not just put try-catch around.
Thanks!
// Update: As discussed below, the answers presented so far do not solve the issue. The closest by now is
([array]($changeRecord.newAttrs | Where{$_.name -eq 'uid'} | Select -ExpandProperty Values))[0]
This, however, fails with an error if the array does not contain any elements. Any idea if this can be handled as well within one line?
Have you tried this: Select-Object -First 1 ?
$uid = $changeRecord.newAttrs |
Where-Object {$_.name -eq 'uid'} |
Select-Object -ExpandProperty Values |
Select-Object -First 1
Select -Index n is only meant to be used on arrays as it will explicitly select from that index in the array. Therefore you will have issues when doing it on a single object. Select -First n will get you n number of objects off the pipeline.
All that said, when I am calling a command and the results may either be a single item or an array of items, I generally declare the variable as an array or cast the value as an array and then even if I get a single object back from the command it will be stored in an array. That way no matter what gets returned, I am treating it the same way. So in your case:
$uid = [array]($changeRecord.newAttrs | Where{$_.name -eq 'uid'} | Select -ExpandProperty Values) | select -Index 0
So, I finally found a solution which is probably fine for me:
$valueArray = [array]($changeRecord.newAttrs | Where{$_.name -eq 'uid'} | Select -ExpandProperty Values)
if(($valueArray -ne $null) -and ($valueArray.Count -gt 0))
{
$value = $valueArray.GetValue(0)
}
else
{
$value = "null..."
}
I put the whole thing into an array first and then check if the array contains any elements. Only if so, I get the first value.
Thanks for everybodys help!
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}}
}