Select-Object - Keep default columns but add one - powershell

I can use Select-Object to choose which columns to show and even add calculated columns. An example:
gci | select *, #{n='LAS'; e={(Get-Date)-$_.LastAccessTime}}
I want add a calculated column but keep the defaut ones. Without the * wildcard I only get my calculated property. With it I get everything. The only workaround I've got to work is to manually list the default property names. Any ideas?

The thing is that that you actually states to display all properties ('*').
So to add to only the standard properties, you first need to get the standard properties.
[string[]]$StdProperties = (Get-ChildItem).PSStandardMembers.DefaultDisplayPropertySet[1].ReferencedPropertyNames
We don't actually want to change the standard property of the objects returned
Get-Childitem | select Name | Get-Member| group TypeName | select Name
Name
----
Selected.System.IO.DirectoryInfo
Selected.System.IO.FileInfo
So we just need to expand on that extracted string array with the new property to use.
$StdProperties += 'LAS'
And finally, to put it to use...
Get-ChildItem | select *, #{n='LAS'; e={(Get-Date) - $_.LastAccessTime}} |
select $StdProperties

Just for fun, building on Abrahams comment, you could do something weird like this:
# get the default properties used on Format-Table
$defaultProps = (((Get-ChildItem | Format-Table | Out-String) -split '\r?\n' |
Where-Object { $_ -match '^\w.*' }) |
Select-Object -First 1) -split '\s+' -ne ''
# now execute the command
Get-ChildItem | Select-Object *, #{n='LAS'; e={(Get-Date)-$_.LastAccessTime}} |
Select-Object ($defaultProps + 'LAS') | Format-Table -AutoSize

Related

Sort CSV powershell script delete duplicate, keep the one with a special value in 3rd column

How do I delete double entriys in a csv by one column and leave the one with one special value in one of the columns?
Example: I got a csv with
Name;Employeenumber;Accessrights
Max;123456;ReadOnly
Berta;133556;Write
Jhonny;161771;ReadOnly
Max;123456;Write
I want to end up with:
Name;Employeenumber;Accessrights
Max;123456;Write
Berta;133556;Write
Jhonny;161771;ReadOnly
I tried by Get-Content Select-Object -unique, but that does not solve the problem that it should only keep the ones with the value "write" at the property Accessrights.
So I have no clue at all
You can use a combination of sorting and grouping ....
#'
Name;Employeenumber;Accessrights
Max;123456;ReadOnly
Berta;133556;Write
Jhonny;161771;ReadOnly
Max;123456;Write
'# |
ConvertFrom-Csv -Delimiter ';' |
Sort-Object -Property Name, Accessrights -Descending |
Group-Object -Property Name |
ForEach-Object {
$_.Group[0]
}

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])

How to strip out everything but numbers in a variable?

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.

Formatting variable with 2 outputs

Code:
$adgroups = Get-ADPrincipalGroupMembership $tag$ | select -ExpandProperty Name | Sort | Select-String "iSite"
Output:
DFSR Managed iSite Enterprise 4.4.542.2 WSA_Rad_A
DFSR Managed iSite Radiology 4.4.516.27 WSA_Rad_A
Basically one command generates two items (output using $variable | out-file C:\file.txt -Append) and when I go to open these in excel they format as one line like this:
DFSR Managed iSite Enterprise 4.4.542.2 WSA_Rad_A DFSR Managed iSite Radiology 4.4.516.27 WSA_Rad_A
Is there a way to break it up // add a new line after each item but still keep them both inside one variable?
Get-ADPrincipalGroupMembership $tag$ | select -ExpandProperty Name | Sort | Select-String "iSite" | ConvertTo-Csv -NoTypeInformation | Out-File C~\Desktop\Sites.csv
I would break up your request a bit.
First, you're using Select -Expand, which is going to discard all of the properties and only return the values for each object's Name. This is a problem because when you export it as a CSV, you're not going to have a heading. I think the lack of header is ultimately leading to the issue you're facing here.
Try this instead:
$adgroups = Get-ADPrincipalGroupMembership $tag$ | Where Name -like "*iSite*" |
select Name | Export-Csv c:\pathto\YourCsv.Csv
Finally, I don't think Select-String is doing you any favors. You could instead use the -like operator.

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}}
}