save the name of VM to array using powershell - powershell

This command saves list of VM to array.
[string]$arrayVM = Get-VM | select Name
When it refers to the first element of the array: $arrayVM[0]
I get the name of VM, but this value look like: #{name=MACHNINE_1_NAME}
I expected only the same name: MACHNINE_1_NAME
How can I do this?

You need to add the -ExpandProperty parameter to your Select-Object command. What this does is expands the value of the specified property and passes that down the pipeline instead of restricting the properties of the current object to be passed down the pipeline. Right now you are passing a Microsoft.HyperV.PowerShell.VirtualMachine object with only the Name property intact. This will instead pass a string with the value of the Name property.
$arrayVM = Get-VM | select -expand Name

[string]$ArrayVM = (Get-VM | Select-Object -Property Name).Name

[string]$arrayVM = Get-VM | select Name
$arrayVM[0].Name

Related

I want to export computer data using Get-CimInstance to a csv but also include the computer name

Right now I'm running
Get-CimInstance -ComputerName $i.DNSHostName -Class CIM_Processor | Select-Object "Name", "NumberOfCores" | Export-Csv -Path .\test.csv -NoTypeInformation -Append`
This will put the CPU name and core count in a CSV fine but how can I add in the hostname as another column?
This is a good case for using a PsCustomObject, which allows you to dynamically create an object with arbitrary properties/values.
$cimProcessor = Get-CimInstance -ComputerName $hostName -Class CIM_Processor
$row = [PSCustomObject]#{
ComputerName = $hostName
Name = $cimProcessor.Name
NumberOfCores = $cimProcessor.NumberOfCores
}
$row | Export-Csv -Path test.csv -NoTypeInformation -Append
In the case where you want to retrieve information from a remote machine first, then you can skip the calculated property and simply select the PSComputerName property instead:
Note: The ellipses ... indicate the code before or after from your original sample.
... | Select-Object PSComputerName, Name, NumberOfCores | ...
Any cmdlet which connects to remote systems via WinRM should have this property automatically set when data is returned over a remote session.
If you are running this from a local session, you could use Select-Object to create a calculated property, then call the hostname command to populate its value:
... | Select-Object "Name", "NumberOfCores", #{
Name = 'ComputerName';
Expression = { hostname };
} | ...
This solution is often suitable for cross platform scripts since a hostname binary is available out of the box on Windows, MacOS, and most major distributions of Linux.
Explaining Calculated Properties
Calculated properties work by defining a hashtable in a specific format and providing the hashtable as a property to be computed just as you would use a string for a real property on the object:
$property = #{
Name = 'PropertyName';
Expression = { 'ScriptBlock' };
}
# Note that the hashtable can be specified inline as shown above
# or as a variable like shown here
[PSCustomObject]#{ Name = 'Bender'; Loves = 'Bending' } |
Select-Object Name, Loves, $property
Keep in mind that within the Expression ScriptBlock, $PSItem/$_ is set to the current object in the pipeline. Use this to reference static or instance properties from the current object you are selecting information from.

Why is this not working? - Trying to save properties in a variable for use multiple times in a function

I am trying to find a way to save the properties for a select statement in PowerShell but it isn't working. I haven't found a way to make an entire statement a literal so that it isn't reviewed until the variable is opened.
Here is what works:
$wsus.GetSummariesPercomputerTarget($CurrentMonthUpdateScope, $ComputerScope) |
Select-Object #{L="WSUSServer";E={$Server}},
#{L="FromDate";E={$($CurrentMonthUpdateScope.FromCreationDate).ToString("MM/dd/yyyy")}},
#{L="ToDate";E={$($CurrentMonthUpdateScope.ToCreationDate).ToString("MM/dd/yyyy")}},
#{L='Computer';E={($wsus.GetComputerTarget([guid]$_.ComputerTargetID)).FullDomainName}},
DownloadedCount,
NotInstalledCount,
InstalledPendingRebootCount,
FailedCount,
Installedcount |
Sort-Object -Property "Computer"
and I am trying to get the properties mentioned (starting just after the Select-Object statement and ending just before the last pipe) placed in a variable so that I can use the same properties multiple times with different scopes.
I have tried this:
$Properties = '#{L="WSUSServer";E={$Server}},
#{L="FromDate";E={$($CurrentMonthUpdateScope.FromCreationDate).ToString("MM/dd/yyyy")}},
#{L="ToDate";E={$($CurrentMonthUpdateScope.ToCreationDate).ToString("MM/dd/yyyy")}},
#{L="Computer";E={($wsus.GetComputerTarget([guid]$_.ComputerTargetID)).FullDomainName}},
DownloadedCount,
NotInstalledCount,
InstalledPendingRebootCount,
FailedCount,
Installedcount'
$wsus.GetSummariesPercomputerTarget($CurrentMonthUpdateScope, $ComputerScope) |
Select-Object $Properties |
Sort-Object -Property "Computer"
While this runs it doesn't give any data and I think it confuses PowerShell.
This gives the same response:
$Properties = "#{L=`"WSUSServer`";E={$Server}},
#{L=`"FromDate`";E={$($CurrentMonthUpdateScope.FromCreationDate).ToString(`"MM/dd/yyyy`")}},
#{L=`"ToDate`";E={$($CurrentMonthUpdateScope.ToCreationDate).ToString(`"MM/dd/yyyy`")}},
#{L=`"Computer`";E={($wsus.GetComputerTarget([guid]$_.ComputerTargetID)).FullDomainName}},
DownloadedCount,
NotInstalledCount,
InstalledPendingRebootCount,
FailedCount,
Installedcount"
Any options, thoughts, etc.?
The -Property argument of Select-Object expects an array, not a string. So something like this:
$Properties = #(#{L="WSUSServer";E={$Server}},
#{L="FromDate";E={$($CurrentMonthUpdateScope.FromCreationDate).ToString("MM/dd/yyyy")}},
#{L="ToDate";E={$($CurrentMonthUpdateScope.ToCreationDate).ToString("MM/dd/yyyy")}},
#{L="Computer";E={($wsus.GetComputerTarget([guid]$_.ComputerTargetID)).FullDomainName}},
"DownloadedCount",
"NotInstalledCount",
"InstalledPendingRebootCount",
"FailedCount",
"Installedcount")
Note, you will need to turn the simple property names into strings within your array.

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.

Select Method returns strings like #{Name=

I'd like to select items from the pipeline using "select" but it returns raw data like: #{Name=MyMachine}
This will not be helpful if, say I want to reboot #{Name=MyMachine} because there is not machine named #{Name=MyMachine}
There's a "MyMachine" but the script does not return just the name.
How do you strip out the "#{Name="}" when selecting individual objects?
Use the -ExpandProperty parameter of Select-Object:
$someobjects | Select-Object -ExpandProperty Name
Another option is echoing the property in a loop:
$something | % { $_.Name }

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