Removing #{} from the output [duplicate] - powershell

This question already has answers here:
How do I write the value of a single property of a object?
(2 answers)
Closed 2 years ago.
The output of the following code is like #{Average = 2}.How can I get the output as Average = 2, Without the #{}.
$cpu = $ENV:COMPUTERNAME |Foreach-Object {
Get-WmiObject -computername $_ win32_processor | Measure-Object -property LoadPercentage -Average | Select Average
}

Firstly, I don't think you need to pipe $env:COMPUTERNAME to Foreach-Object, since its of type System.String, not an array or any other type of collection. Would be easier to just use -ComputerName $env:COMPUTERNAME directly. You can see what the type is with ($env:COMPUTERNAME).GetType(). Also have a look at about_environment_variables for more information about Windows environment variables in PowerShell.
Secondly, as #Mathias R. Jessen suggested in the comments, you should use -ExpandProperty to expand the property #{Average = 2} to 2.
Modified command
Get-WmiObject -ComputerName $env:COMPUTERNAME -Class Win32_Processor `
| Measure-Object -Property LoadPercentage -Average `
| Select-Object -ExpandProperty Average
You could also run Get-Help Select-Object -Parameter ExpandProperty to see what ExpandProperty does for Select-Object.
-ExpandProperty <String>
Specifies a property to select, and indicates that an attempt should be made to expand that property. Wildcards are permitted in the property name.
For example, if the specified property is an array, each value of the array is included in the output. If the property contains an object, the properties of that object are displayed in the output.
Required? false
Position? named
Default value None
Accept pipeline input? False
Accept wildcard characters? false
Also as a side note mentioned in the comments by #mklement0, WMI cmdlets(e.g. Get-WmiObject) have been superseded by CIM cmdlets(e.g. Get-CimInstance) in PowerShell v3 (released in September 2012).. This is also pointed out to you when you run Get-Help Get-WmiObject:
Starting in Windows PowerShell 3.0, this cmdlet has been superseded by Get-CimInstance
And also in this Use CIM cmdlets not WMI cmdlets article. Another reason is that the future is PowerShell Core, which doesn't support WMI cmdlets anymore. You can have a look at this answer for more information.
With all that said, here is the equivalent CIM command using Get-CimInstance.
Get-CimInstance -ClassName Win32_Processor `
| Measure-Object -Property LoadPercentage -Average `
| Select-Object -ExpandProperty Average
Which will work on both Windows PowerShell and PowerShell Core.

Related

PowerShell - Pass array as an optional parameter value

I'm pretty new to PowerShell.
I'm trying to pass an array of server names as an optional parameter value to get the last bootup time for a list of servers.
Example 1
$serverList = #('server1"', '"server2"', '"server3"', '"server4"', '"server5"')
Get-CimInstance -ComputerName $serverList -ClassName win32_operatingsystem | Select-Object csname, lastbootuptime
Example 2
Get-CimInstance -ComputerName server1,server2,server3,server4,server5 -ClassName win32_operatingsystem | Select-Object csname, lastbootuptime
In example 1, I get an error that says it can't connect to the
servers.
In example 2, it works.
I'm likely missing a key piece of fundamental knowledge as to why what I'm doing wasn't working. What am I missing?
Thanks for the help.
In the first example you are over-doing things with the quotes. (also server1 has an ending double quote, but no starting double quote..)
By putting the servers inside single quotes ', the text inside it is taken literally, so you are feeding the cmdlet with names like "server2", so including the double-qoute characters.
These quotes obviously don't belong to the server name.
BTW: Not an error, but you don't need the #() when creating the server names array.
This would be a better way of setting up your string array, where you can use either single or double quote characters, but not both:
$serverList = 'server1', 'server2', 'server3', 'server4', 'server5'
Get-CimInstance -ComputerName $serverList -ClassName win32_operatingsystem | Select-Object csname, lastbootuptime
You have also noticed that when used as parameters to a cmdlet, you don't even need the quotes, and the elements are interpreted as strings, as long as they do not contain space characters:
Get-CimInstance -ComputerName server1,server2,server3,server4,server5 -ClassName win32_operatingsystem | Select-Object csname, lastbootuptime

Powershell command to delete everything that starts with _

If I use the code:
get-wmiObject win32_computersystem | select *
I get all the properties that this wmiobject has. I want to filter it, so that all the properties starting with _ (underscore) are filtered out. But I can't find the command to do this.
Could someone help me out?
You should use Get-CimInstance instead of Get-WmiObject. If you read the help for Select-Object you will learn that you can include desired properties and you can exclude properties if you like:
Get-CimInstance -ClassName CIM_ComputerSystem |
Select-Object -ExcludeProperty __* -Property *
Disclaimer: I have no knowledge of PowerShell.
From Select-Object/Parameters, I would try -ExcludeProperty
Specifies the properties that this cmdlet excludes from the operation. Wildcards are permitted.
get-wmiObject win32_computersystem | Select-Object -ExcludeProperty _* -Property *

Filtering a Get-printer variable output

I need to get all the printers named with a printer name starting with P0
I'm new to PowerShell and the command get-printer did not support my syntax for the filtering. My output variable is empty.
I have tried filtering the command results and tried filtering the content of the results variable with all printers without success.
$PrinterList = Get-Printer -ComputerName "PrintServer" -Filter {name -like 'P0'}
Or
$PrinterList = Get-Printer -ComputerName "PrintServer"
$PrinterSort = $PrinterList.Name | Where-Object {$PrinterList.Name -Like "P0"}
Per the other answer, you need to include one or more wildcard characters in your string (e.g * for 0 or more characters, or ? for a single character).
You can also simplify your code to use a wildcard in the -Name parameter on the cmdlet directly:
$PrinterList = Get-Printer -ComputerName "PrintServer" -Name "P0*"
You need a wildcard for your -like, e.g. name -like 'P0*'
This should work with both of your solutions.

Powershell get installed program script doesn't return computer name

I'm trying to get a list of installed programs off a group of remote servers. I'm able to get the program name but not return the system name. Below is my script.
$computerfile = get-content "D:\Users\Admin\Docs\PrimaryServers.txt"
ForEach ($computer in $computerfile) {
Get-WmiObject Win32_Product -ComputerName $computer |
Select-Object SystemName,Name,Version,PackageName,Installdate,Vendor |
Format-Table -AutoSize
}
Below is my output
First, -ComputerName can take an array of names so by looping you are going to increase the time because the loop will be in serial where utilizing the array for computername will be in parallel.
Second, it's best practice to use the CIM cmdlets in place of the WMI cmdlets. They operate over WSMAN by default and are easier to work with.
Third, Win32_Product forces a consistency check so reading the Uninstall registry keys is usually superior.
Lastly, SystemName isn't a property name that is returned by Get-WMIObject. PSComputerName is the property you are looking for and you can make a Calculated Property from it.
$computerfile = get-content "D:\Users\Admin\Docs\PrimaryServers.txt"
Get-CimInstance Win32_Product -ComputerName $Computerfile |
Select-Object #{n=SystemName;e={$_.PSComputerName}},Name,Version,PackageName,Installdate,Vendor |
Format-Table -AutoSize
Another approach is to use the Invoke-Command where it automatically extends the result with the PSComputerName column
First build up the script blocks to use as query
Block 1 is my approach for both x32 and x64 implementations. Consider this as an alternative because I has some issues with the proposed implementation.
$block1={
# Query x64 bit applications
$queryPath="HKLM:\Software\Microsoft\Windows\CurrentVersion\Uninstall\*"
Get-ItemProperty $queryPath | Select-Object -Property DisplayName, Publisher, InstallDate, DisplayVersion
# Query x32 bit applications
$queryPath="HKLM:\SOFTWARE\Wow6432Node\Microsoft\Windows\CurrentVersion\Uninstall\*"
Get-ItemProperty $queryPath | Select-Object -Property DisplayName, Publisher, InstallDate, DisplayVersion
}
Block 2 is the proposed approach on this question
$block2={
Get-CimInstance Win32_Product | Select-Object Name,Version,PackageName,Installdate,Vendor
}
For either $block1 or $block2 execute remotely on a server list
Invoke-Command -ComputerName $computernames -ScriptBlock $block1
And one record looks like this
DisplayName : Microsoft Visual C++ 2013 x86 Additional Runtime - 12.0.21005
Publisher : Microsoft Corporation
InstallDate : 20161202
DisplayVersion : 12.0.21005
PSComputerName : MECDEVAPP01
RunspaceId : 4b8cc747-da25-4c6e-b108-0ca3138c0335

How to list all attributes of "-class" in powershell

I am running powershell command below
Get-wmiobject -class win32_logicaldis
I want to list all other attributes for -class. How can I do it?
I tried get-wmiobject | get-member, it was asking me to input a class value which I dont know what options I have.
Get-WMIObject -List| Where{$_.name -match "^Win32_"} | Sort Name | Format-Table Name