powershell select-object property AND expandproperty - powershell

Trying to execute a Select-Object, but i can't seem to return property and a value from a key-value list property. There are 3 properties i want returned RunStart, Message and 'tableName' from this Parameters property.
I get too much with this:
|Select-Object -Property Parameters,RunStart,Message
Parameters RunStart Message
---------- -------- -------
{[tableName, AHROR012], [schemaName, dbo]...} 11/14/2019 5:39:06 PM Operation on target failed
But I dont get the RunStart or Message when i do this:
|Select-Object -ExpandProperty Parameters -Property tableName,RunStart,Message
Key Value
--- -----
tableName AHROR012
How do i do it to get:
Parameters.tableName RunStart Message
---------- -------- -------
AHROR012 11/14/2019 5:39:06 PM Operation on target failed
THANKS!!!

... | Select-Object -Property #{
Name='ParametersTableName';
Expression={ $_.Parameters.tableName }
}, RunStart, Message

A more elegant solution would be to use a 2nd select statement:
... | select RunStart,Message -ExpandProperty Parameters | Select RunStart,Message,tableName

Related

Select-object -property parameter not displaying multiple column

Currently when I try
get-process | Select-Object -property NAME,Id,CPU,PM
Only the Name column is displayed in vscode in ubuntu
Name
----
(sd-pam)
accounts-daemon
However if i switch the position of the value 'name' it would work but it seems to only display till where the 'name property is?
PS /home/limyk14> get-process | Select-Object -property Id,CPU,name,PM
Id CPU Name
-- --- ----
1506 0 (sd-pam)
PS /home/limyk14> get-process | Select-Object -property Id,CPU,PM,name
Id CPU PM Name
-- --- -- ----
1506 0 880640 (sd-pam)
797 2.77 49152 accounts-daemon
Thanks to #iRon and #mclayton
It is actually due to the length of a few processes that had really long names
vs code itself was one of them,
Format-table var1,2,3,4 -autosize didn't help neither did wrapping.
However the suggestion of using a hash table and declaring the width works.
format-table #{name = 'name';expression = 'name'; width = 7}, cpu, id, pm

powershell - How refer custom expression property on single one select-object

can you help me with this simple example script?
How do I refer to "custom expression property" on single one "select-object"?
I would like: single "select-object"
Get-Process | Select-Object Id, 
    #{name="MyProp"; expression={$_.id}},
    #{name="MyPropRef"; expression={$_.MyProp}}
...but third property "MyPropRef" is not displayed!
Id MyProp MyPropRef
-- ------ ---------
3780 3780
While with double select-object piped, "MyPropRef" is displayed
Get-Process | Select-Object Id, 
    #{name="MyProp"; expression={$_.id}} | Select-Object *,
    #{name="MyPropRef"; expression={$_.MyProp}}
Id MyProp MyPropRef
-- ------ ---------
3780 3780 3780
Thanks
Calculated properties only operate on the input objects' original properties, they cannot refer to each other.
If you need to add additional properties based on previously calculated properties, you indeed need another (expensive) Select-Object call.
Your command:
Get-Process | Select-Object Id,
#{name="MyProp"; expression={$_.id}},
#{name="MyPropRef"; expression={$_.MyProp}}
creates a .MyPropRef property, but its value is $null, because the System.Diagnostics.Process instances that Get-Process outputs themselves do not have a .MyPropRef property.
If you want to make do with a single Select-Object call without repetition, you can define the script blocks used in the calculated properties in variables beforehand and reuse them across calculated property definitions; e.g.:
$myPropExpr = { $_.id }
Get-Process | Select-Object Id,
#{ name="MyProp"; expression=$myPropExpr },
#{ name="MyPropRef"; expression={ "!" + (& $myPropExpr) }}
This would yield something like:
Id MyProp MyPropRef
-- ------ ---------
3780 3780 !3780
...

Concatenating non-unique values alongside a unique field in PowerShell

I have the following set of queries which retrieve a set of data, merge it down so I just get the unique values and add a number to each of them (so I can select that particular item later).
$allMoveRequests = Get-MoveRequest -DomainController server |
select Alias,Status,TargetDatabase,BatchName
$optNum=1
$AllMoveBatches = #($allMoveRequests | Sort-Object -Property BatchName |
Select-Object BatchName,TargetDatabase -Unique) |
Select #{Name="Option";Expression={$optNum;$optNum++}},BatchName,TargetDatabase
$AllMoveBatches | Format-Table -AutoSize | Out-String|% {Write-Host $_}
This returns :
Option BatchName TargetDatabase
------ --------- --------------
1 Batch1 Database1
2 Batch2 Database2
etc. That works as it should, but what I'd like to add is the Status value from those batches, combined where there is more than one rather than creating duplicate entries. For instance, if I simply add Status into the second bit of code I end up with :
Option BatchName TargetDatabase Status
------ --------- -------------- ------
1 Batch1 Database1 Completed
2 Batch1 Database1 In Progress
3 Batch2 Database2 Completed
while what I'd ideally like would be :
Option BatchName TargetDatabase Status
------ --------- -------------- ------
1 Batch1 Database1 Completed,InProgress
2 Batch2 Database2 Completed
I've tried using an expression in the select statement to query all the relevant Status entries and apply -Unique to them, but that just returns all Status entries across all batches, not just those relevant to the current Batch line.
Is there a way to achieve this?
It's not pretty, and it might not be very performant with lots of data, but here's one way to do it...
First, lets create some sample data:
$data = #(
(new-object PSObject -Property ([ordered] #{
"BatchName" = "Batch1"
"TargetDatabase" = "Database1"
"Status" = "Completed"
})),
(new-object PSObject -Property ([ordered] #{
"BatchName" = "Batch1"
"TargetDatabase" = "Database1"
"Status" = "In Progress"
})),
(new-object PSObject -Property ([ordered] #{
"BatchName" = "Batch2"
"TargetDatabase" = "Database2"
"Status" = "Completed"
}))
)
now, process it:
Set-Variable -Name "optNum" -Option AllScope -Value 1
$results = #( $data | group-object BatchName, TargetDatabase ) `
| select-object #{Name="Option";Expression={$optNum; $optNum++}},
#{Name="BatchName";Expression={$_.Group[0].BatchName}},
#{Name="TargetDatabase";Expression={$_.Group[0].TargetDatabase}},
#{Name="Status";Expression={$_.Group.Status -join ", "}} `
| sort-object -Property BatchName
and show the result:
PS> $results
Option BatchName TargetDatabase Status
------ --------- -------------- ------
1 Batch1 Database1 Completed, In Progress
2 Batch2 Database2 Completed
What it's doing is grouping to select the unique combinations of BatchName and DatabaseName and then to make the results it's selecting the BatchName and DatabaseName from the first item in each group, and concatenating all of the Status properties from the items in that group (you could also process the statuses in the Status Expression if you wanted to e.g. sort, filter or de-dupe them within each group).
Note that I've moved your original sort-object BatchName to the end of the pipeline. There's no point sorting, say 1000 objects only to throw half of them away - you might as well sort at the end.
And I could only get your "Option" counter to work by using Set-Variable to make it AllScope as the $optNum++ wasn't incrementing the variable properly when I used $optNum = 1 to initialise it.
mclayton's answer should be the accepted one, but here's a slightly more concise version that uses one of my favorite Powershell idioms: Foreach with a -Begin scriptblock {$i=1} that executes only once.
[pscustomobject]#{BatchName = 'Batch1';TargetDatabase='Database1';Status='Completed'},
[pscustomobject]#{BatchName = 'Batch1';TargetDatabase='Database1';Status='In Progress'},
[pscustomobject]#{BatchName = 'Batch2';TargetDatabase='Database2';Status='Completed'} |
Group BatchName, TargetDatabase |
%{$i=1}{ [pscustomobject]#{Option = $i++
BatchName = $_.Group[0].BatchName
TargetDatabase = $_.Group[0].TargetDatabase
Status = $_.Group.Status -join ','}
}

powershell iterate all users and display recent lnk files

Iterate all windows $users and display the recent .lnk files from a specific path!
I have tried importing this module - https://gist.github.com/picheljitsu/cc2ed99cbae7caad3abb0928cd8a286b
Get-RecentFiles and I want to iterate with $users after getting the users with get-localuser
$user = (Get-LocalUser | Select-Object Name) |
ForEach-Object { Get-RecentFiles $user }
should display recent files of all users recent directory..
Directory: C:\Users\admin\AppData\Roaming\Microsoft\Windows\Recent
Mode LastWriteTime Length Name
---- ------------- ------ ----
d----- 6/30/2019 6:59 PM AutomaticDestinations
d----- 7/1/2019 3:21 PM CustomDestinations
Directory: C:\Users\user2\AppData\Roaming\Microsoft\Windows\Recent
Mode LastWriteTime Length Name
---- ------------- ------ ----
d----- 6/30/2019 6:59 PM AutomaticDestinations
d----- 7/1/2019 3:21 PM CustomDestinations
The result of Get-LocalUser | Select-Object Name is an array of users. When you pass this array to the pipeline, it will "unwrap" its items and pass them one at a time, and this item will be declared as $_ variable.
Passing Arrays to Pipeline
If a function returns more than one value, PowerShell wraps them in an array. However, if you pass the results to another function inside a pipeline, the pipeline automatically "unwraps" the array and processes one array element at a time.
ExpandProperty parameter is used to convert the object property Name to string to be used in the Get-RecentFiles function.
Modify your code and try this:
Get-LocalUser | Select-Object -ExpandProperty Name | Foreach-Object {Get-RecentFiles $_}
Update
The above code will get some errors for the disabled users (e.g: administrator, guest). To solve this, you have to only get the enabled users as follows:
Get-LocalUser | Where-Object Enabled | Select-Object -ExpandProperty Name | Foreach-Object {Get-RecentFiles $_}

How to access list value in Get-EC2Instance's RunningInstance method?

I'm trying to retrieve the instanceid, public dns name, and "Name" tag from the object returned by get-ec2instance.
$instances = foreach($i in (get-ec2instance)) '
{ $i.RunningInstance | Select-Object InstanceId, PublicDnsName, Tag }
Here's the output:
InstanceId PublicDnsName Tag
---------- ------------- ---
myInstanceIdHere myPublicDnsName {Name}
... ... {Name}
I would like to be able to access {Name} using the line of code above and print its value in this output. I've done a little bit of research since this initial posting, and found...
PS C:\Users\aneace\Documents> $instances[0].Tag.GetType()
IsPublic IsSerial Name BaseType
-------- -------- ---- --------
True True List`1 System.Object
Between this and the AWS docs, I think Tag refers to this list, but I'm not certain. I can access a table that prints key and value columns by calling $instances[0].Tag, but my problem now is that I would like that Value to be the output to my first table instead of the {Name} object. Any suggestions?
Per the documentation, the Tag property is a list of Tag objects. So in general, there will be multiple keys/values stored there. Are you assuming that in your case there is only 1?
Select-Object allows you to grab not just raw property values, but calculated values as well. Let's say you just want a comma-delimited list of the Values from the Tag objects in the list. Here's how you would do it:
$instances = Get-EC2Instance `
|%{ $_.RunningInstance } `
| Select-Object InstanceId,PublicDnsName,#{Name='TagValues'; Expression={($_.Tag |%{ $_.Value }) -join ','}}
The elements of $instances will now have a property TagValues which is a string consisting of the Value from all Tags associated with the instance.
Here is how to extract tags into a flat object along with other properties
$region = 'us-west-2'
$instances = (Get-Ec2Instance -Region $region).Instances | select `
#{Name="ServerName";Expression={$_.tags | where key -eq "Name" | select Value -expand Value}},`
InstanceType ,`
InstanceId,`
ImageId,`
#{Name="Role";Expression={$_.tags | where key -eq "Role" | select Value -expand Value}},`
#{Name="Group";Expression={$_.tags | where key -eq "Group" | select Value -expand Value}},`
#{Name="Subsystem";Expression={$_.tags | where key -eq "subsystem" | select Value -expand Value}},`
#{Name="State";Expression={$_.State.Name}},`
#{Name="Region";Expression={$region}}
$instances | Sort-Object -Property State, ServerName | Format-Table