Concatenate string with object in Powershell - powershell

Currently I want to get a list of active user on Windows 10 using Powershell.
After some searching I found this helps:
Get-LocalUser | Where-Object -Property Enabled -eq True
And here is the output:
Name Enabled Description
---- ------- -----------
User_1 True
User_2 True
I just want to concatenate strings to a list of values of Name column from above, which will be like below:
Active user(s): User_1, User_2
Do you have any idea how I can do that? I'm just a non-tech guy trying to learn some useful command so forgive me if this is a basic to you.

You can do the following:
# Retrieve the name values
$Users = Get-LocalUser |
Where-Object Enabled -eq True | Select-Object -Expand Name
# Create the output string
"Active user(s): {0}" -f ($Users -join ', ')
Using -Expand (or -ExpandProperty) from Select-Object, the target property's value is returned rather than the object that contains the property.
-f is the string format operator. It uses substitution for the {position} syntax. The -join operator creates a string from a list with , as the delimiter.

Related

Multiple rows in a grid [duplicate]

This question already has answers here:
Export hashtable to CSV with the key as the column heading
(2 answers)
Closed 4 years ago.
I'm trying to list all ad group memberships of specific users. The input would be a string of logins split with a comma 'login1,login2'.
So I go over each user and list their memberships with the username as title. Somehow it only shows the first entry. Also it shows the user groups in one row and I don't know how to change that.
Code below:
$users = $logon -split ','
$q = #()
foreach ($user in $users) {
$usernm = Get-ADUser -Filter 'samAccountName -like $user' | select Name
$useraccess = Get-ADPrincipalGroupMembership $user | Select-Object Name
$userobj = New-Object PSObject
$userobj | Add-Member Noteproperty $usernm.Name $useraccess.Name
$q += $userobj
}
Expected output would be something like:
fullnameuser1 fullnameuser2 list of users goes on...
------------- ------------- ------------------------
adgroup1 adgroup3 ...
adgroup2 adgroup4
... ...
In principle this would also mean that if i typed $q.'fullnameuser1' output would be:
fullnameuser1
-------------
adgroup1
adgroup2
...
Whenever the code is ran, it will only ever add the first user's access, also returning all groups on one row. So somehow I need to go over all the group memberships and add a row for each one.
First and foremost, PowerShell does not expand variables in single-quoted strings. Because of that Get-ADUser will never find a match unless you have a user with the literal account name $user. Also, using the -like operator without wildcards produces the same results as the -eq operator. If you're looking for an exact match use the latter. You probably also need to add nested quotes.
Get-ADUser -Filter "samAccountName -eq '${user}'"
Correction: Get-ADUser seems to resolve variables in filter strings by itself. I verified and the statement
Get-ADUser -Filter 'samAccountName -eq $user'
does indeed return the user object for $user despite the string being in single quotes.
If you want a fuzzy match it's better to use ambiguous name resolution.
Get-ADUser -LDAPFilter "(anr=${user})"
You may also want to avoid appending to an array in a loop, and adding members to custom objects after creation. Both are slow operations. Collect the loop output in a variable, and specify the object properties directly upon object creation.
$q = foreach ($user in $users) {
...
New-Object -Type PSObject -Property {
$usernm.Name = $useraccess.Name
}
}
Lastly, I'd consider using the user's name as the property name bad design. That would be okay if you were building a hashtable (which is mapping unique keys to values), but for custom objects the property names should be identical for all objects of the same variety.
New-Object -Type PSObject -Property {
Name = $usernm.Name
Group = $useraccess.Name
}
Basily query all the users and store it in $users, example:
Get-ADUser -Filter * -SearchBase "dc=domain,dc=local"
And then you can export the results as csv or a table.
To Export as CSV :
Get-ADPrincipalGroupMembership <Username> | select name, groupcategory, groupscope | export-CSV C:\data\ADUserGroups.csv`
To Format the result as Table in the console itslef :
Get-ADPrincipalGroupMembership <Username> | select name, groupcategory, groupscope | Format-Table

Powershell capturing group in pipeline select-object with calculated property

Given the following input XML sample -- assume multiple LogMessage entries.
<LogMessages>
<LogMessage time="2017-12-08 11:44:05.202" messageID="A10">
<![CDATA[Long non-xml string here containing <TS "2017120811431218"> somewhere in the body"]>
</LogMessage>
</LogMessages>
I am using the following code to capture the values of attributes time, messageID, and capture a group in the CDATA.
[xml]$xml = Get-Content input.xml
$xml.LogMessages.LogMessage | Where-Object {$_.messageID -eq "A10"} | Select-Object -Property time,messageID,#{Name="A10Timestamp"; Expression=$_."#cdata-section" -match '<TS "(?<group>[0-9]{16})">' | Select-Object $Matches['group'] }} `
| Export-Csv output.csv -NoTypeInformation
Output looks like:
time messageID Group
---- --------- ---------------
2017-12-08 11:43:12.183 S6F1 #{2017120811431218=}
The #{ and } wrapping the captured group value is undesired. I am concerned about this particular use of the $Matches variable...I think what gets printed is a Match object and not the group string that it matched on... or something like this.
What is going on and how do I get the entries in the Group column appear as 2017120811431218 and not #{2017120811431218=}?
The Match operator returns a boolean and populates the $Matches variable with the matching results.
In other words, you should void what is returned by the -Match operator (and not pipe it) and than simply return the $Matches['group'] to the Expression:
Expression={$Void = $_."#cdata-section" -match '<TS "(?<group>[0-9]{16})">'; $Matches['group']}

Extracting text from output

I am creating my first application with VS and PowerShell and need to get the name of a service from my listview. The output of the selection looks like this:
ComputerName Status Name DisplayName
------------ ------ ---- -----------
PC Running Appinfo Application Information
What I want to do is get the value Appinfo from the Name column and assign it to a variable. I've had no luck with regex, but then again I am a beginner so I could be doing something wrong. Is there an easy way to do this?
The output you're currently getting is a formatted (tabular) view on selected properties of an object (namely the properties ComputerName, Status, Name, and DisplayName). You can get the value of a particular property by expanding it via the Select-Object cmdlet:
$name = ... | Select-Object -Expand Name
You could also store the object in a variable and access the property via dot-notation:
$obj = ...
$name = $obj.Name
Beware that if a cmdlet outputs multiple objects the variable will contain an array:
PS C:\> $services = Get-Service
PS C:\> $services.GetType().FullName
System.Object[]
PS C:\> $services.Count
136
You can access properties of a member object by index:
$services[42].Name
or by selecting a specific object via its properties:
$services | Where-Object { $_.DisplayName -eq 'Application Information' } |
Select-Object -Expand Name
Since PowerShell v3 you can also use the dot-property notation to get the value of a particular property of all array members:
$services.Name
Prior to PowerShell v3 this would have thrown an error, because the array object doesn't have a property Name.

How to get the value of a particular propery from the result of a powershell command

I have a variable $ results which has the value :
SESSIONNAME USERNAME ID STATE TYPE DEVICE
rdp-tcp#1 account17 7 Active rdpwd
I want to get the value of ID alone and use it in a different query.
I tried the following ways :
1.$idValue = #($result | %{ $_.ID }) - but it was not getting the value.
2.$result |Select -ExpandProperty ID - I was getting the error 'Select-Object : Property "ID" cannot be found.'
How to get the value of the property ID alone from the result?
The output of the qwinsta/query commands are strings, not objects, so there isn't a property ID to print. You need to transform the strings into objects if you want the fields as properties:
query session | ? { $_ -match '^[ >](\S+) +(\S*?) +(\d+) +(\S+)' } |
select #{n='Service';e={$matches[1]}},
#{n='Username';e={$matches[2]}},
#{n='ID';e={$matches[3]}},
#{n='Status';e={$matches[4]}} | % {
$_.ID
}
Or, if you're just interested in the ID, you could do a regular expression replacement like this:
$account = 'account17'
$pattern = '^[ >]\S+ +\S*? +(\d+) +\S+.*'
(query session $account | select -Skip 1) -replace $pattern, '$1'
This is the format to refer to a single property properly. I don't see your command to create your RDP $result, so I'll example get-process, encapsulate it with () and tack an ().ID to the end. Works with any property, not just.ID
(get-process | where {$_.Name -eq "Powershell"}|select ID).ID
# or
$MYID = (get-process | where {$_.Name -eq "Powershell"}|select ID).ID
$MYID
Another option is -split:
One solution, using V4:
($result).ForEach({($_ -split '\s+')[2]}) -match '\d'

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