How to execute several cmdlets in powershell script? - powershell

I have written this script to get some information about my Virtual Machine. When I execute this script the last two cmdlets (lines) don't execute, but when I execute them alone they run properly.
Get-CimInstance Win32_LogicalDisk -Filter "DriveType=3" | Select-Object DeviceID, SystemName,
#{n='Size (GB)'; e={$_.Size / 1GB -as [int]}},
#{n='Freespace (GB)'; e={$_.Freespace / 1GB -as [int]}};
$TotalMemory = (Get-CimInstance Win32_OperatingSystem).TotalVisibleMemorySize / (1024*1024)
$UsedMemory = (Get-CimInstance Win32_OperatingSystem).FreePhysicalMemory / (1024*1024)
$TotalMemory = [math]::Round($TotalMemory,2)
$UsedMemory = [math]::Round($UsedMemory,2)
$TotalMemory
$UsedMemory
Get-CimInstance Win32_Processor | Select-Object -Property NumberOfCores;
Get-CimInstance Win32_Processor | Measure-Object -Property LoadPercentage -Sum | Select-Object Sum;
What is the problem?
Any comments would be appreciated.

This question has been asked a million times. Format-table is being implicitly run, and it doesn't handle different sets of columns well. All the objects are there. You can pipe the whole script to format-list. You can put get-date at the very beginning. A known object with a format file at the beginning fixes it. You can output more than 4 properties with the first object. I tried to ask for a warning to be added a while ago: format-table should at least warn when it doesn't display properties #7871
Looks like out-gridview has similar struggles: Not all properties displayed

This appears to be one of PowerShell's weird quirks. I am not sure why it happens, but if someone else does I will happily edit my answer to include it.
You will need to specifically tell it to write the output to the console. There are a couple ways of doing this.
The first, and probably messiest, would be to pass it as a parameter to Write-Host or Write-Output.
Write-Host (Get-CimInstance Win32_Processor | Select-Object -Property NumberOfCores)
Write-Host (Get-CimInstance Win32_Processor | Measure-Object -Property LoadPercentage -Sum | Select-Object Sum)
(Another way of doing this would be to assign them both to variables, and pass the variables to the cmdlet)
The second way would be to pipe it to Write-Host or Write-Output
Get-CimInstance Win32_Processor | Select-Object -Property NumberOfCores | Write-Host
Get-CimInstance Win32_Processor | Measure-Object -Property LoadPercentage -Sum | Select-Object Sum | Write-Host
And finally, the third (and in my opinion cleanest) way would be to pipe it to a code block that references the property directly
Get-CimInstance Win32_Processor | %{$_.NumberOfCores}
Get-CimInstance Win32_Processor | Measure-Object -Property LoadPercentage -Sum | %{$_.Sum}
Hope this helps!

Related

Out-gridview does not sorting results

I have a script that I am trying to collect drive letters from a list of servers (as well as used space and free space) and then gridview the results out.
$servers = Get-Content "path.txt"
foreach ($server in $servers) {
Invoke-Command -ComputerName $server {Get-PSDrive | Where {$_.Free -gt 0}}
Select-Object -InputObject usedspace,freespace,root,pscomputername |
Sort-Object root -Descending | Out-Gridview
}
I can get it to display the drive information for each server on the list but gridview does not work. I have tried moving the brackets around (before and after gridview) as well as piping elements but have had no luck.
Can anyone advise me as to what I am doing wrong? I feel like it is something simple but all of the examples I am finding online do not use the foreach command which I think has to do with throwing it off.
Your Select-Object is missing pipeline input - pipe the Invoke-Command call's output to it.
Instead of -InputObject, use -Property:
Note: -InputObject is the parameter that facilitates pipeline input, and is usually not meant to be used directly.
As with Sort-Object, -Property is the first positional parameter, so you may omit -Property in the call below.
foreach ($server in Get-Content "path.txt") {
Invoke-Command -ComputerName $server { Get-PSDrive | Where { $_.Free -gt 0 } } |
Select-Object -Property usedspace, freespace, root, pscomputername |
Sort-Object root -Descending |
Out-Gridview
}
Also note that -ComputerName can accept an array of computer names, which are then queried in parallel, so if you want to query all computers and then call Out-GridView only once, for the results from all targeted computers:
Invoke-Command -ComputerName (Get-Content "path.txt") {
Get-PSDrive | Where Free -gt 0
} |
Select-Object -Property usedspace, freespace, root, pscomputername |
Sort-Object root -Descending |
Out-Gridview
To group the results by target computer, use
Sort-Object pscomputername, root -Descending
If you'd rather stick with your sequential, target-one-server-at-a-time approach, change from a foreach statement - which cannot be used directly as pipeline input - to a ForEach-Object call, which allows you to pipe to a single Out-GridView call:
Get-Content "path.txt" |
ForEach-Object {
Invoke-Command -ComputerName $_ { Get-PSDrive | Where Free -gt 0 }
} |
Select-Object -Property usedspace, freespace, root, pscomputername |
Sort-Object root -Descending |
Out-Gridview

How to change an output formed by hashstables Powershell

I am storing the following query value in a variable:
$unquotedPaths = Get-WmiObject -Class Win32_Service | Select-Object -Property Name,DisplayName,PathName,StartMode | Select-String "auto"
The problem starts when i print that variable becouse the variable takes from the query an object which is formed by hashtables like in this output:
PS C:\Users\pc> Get-WmiObject -Class Win32_Service | Select-Object -Property Name,DisplayName,PathName,StartMode | Select-String "auto"
#{Name=AGMService; DisplayName=Adobe Genuine Monitor Service; PathName="C:\Program Files (x86)\Common Files\Adobe\AdobeGCClient\AGMService.exe"; StartMode=Auto}
#{Name=AGSService; DisplayName=Adobe Genuine Software Integrity Service; PathName="C:\Program Files (x86)\Common Files\Adobe\AdobeGCClient\AGSService.exe"; StartMode=Auto}
#{Name=asComSvc; DisplayName=ASUS Com Service; PathName=C:\Program Files (x86)\ASUS\AXSP\1.01.02\atkexComSvc.exe; StartMode=Auto}
#{Name=AudioEndpointBuilder; DisplayName=Compilador de extremo de audio de Windows; PathName=C:\WINDOWS\System32\svchost.exe -k LocalSystemNetworkRestricted -p; StartMode=Auto}
How i can get and output like this:
Name DisplayName PathName Startmode
---------- ------------- ------------ ------------
ExampleName ExampleDisplayName C:\Example Auto
Select-String is meant to search and match patterns among strings and files, If you need to filter an object you can use Where-Object:
$unquotedPaths = Get-WmiObject -Class Win32_Service |
Where-Object StartMode -EQ Auto |
Select-Object -Property Name,DisplayName,PathName,StartMode
If the filtering required more complex logic you would need to change from Comparison Statement to Script Block, for example:
$unquotedPaths = Get-WmiObject -Class Win32_Service | Where-Object {
$_.StartMode -eq 'Auto' -and $_.State -eq 'Running'
} | Select-Object -Property Name,DisplayName,PathName,StartMode

Retrieving CPU details in Powershell

I am planning to extract the CPU details to my powershell requirement. Below is the highlighted parameter that I am trying to extract.
I have tried using Get-WmiObject Win32_Process or Get-Process but no luck with it. Can you guide with the cmdlet which can be helpful for this
Updated Question
Get-Counter '\Process(*)\% Processor Time' |
Select-Object -ExpandProperty countersamples |
Select-Object -Property instancename, cookedvalue|
Sort-Object -Property cookedvalue -Descending |
Select-Object| ft InstanceName,#{L='CPU';E={($_.Cookedvalue/100).toString('P')}} -AutoSize
I am using this code as suggested in the below comments. and below is the output which I am receiving.
However if you compare the value for PS output and the task manager screenshot, its quite different, since in task manager most of them are 0
Updated Part 2
I have extracted this code from another post.
$NumberOfLogicalProcessors=(Get-WmiObject -class Win32_processor | Measure-Object -Sum NumberOfLogicalProcessors).Sum
(Get-Counter '\Process(*)\% Processor Time').Countersamples | Sort cookedvalue -Desc | ft -a instancename, #{Name='CPU %';Expr={[Math]::Round($_.CookedValue / $NumberOfLogicalProcessors)}}
This may be working, but I would like to get your opinions on these since the value for this is dynamic and pretty difficult to verify
try this:
$Utilization = #()
Get-WmiObject Win32_PerfFormattedData_PerfProc_Process | Sort-Object -Property PercentProcessorTime -descending | ? { $_.name -inotmatch '_total|idle' } | % {$Utilization += [PSCustomObject]#{'Process Name' = $_.Name; 'pid' = $_.IDProcess; 'Usage' = $_.PercentProcessorTime}}

Powershell -lt and -gt giving opposite of expected results [duplicate]

This question already has an answer here:
How can I store output from Format-Table for later use
(1 answer)
Closed 3 years ago.
In the below code, if I add a where-object, -lt & -gt are giving opposite of expected results.
I'm sure the reason is I'm stupid, but in what specific way am I messing up?
This part gives the expected results, where in my case, the single drive has %Free of 39.8
Get-WmiObject -Namespace root\cimv2 -Class win32_logicaldisk | where-object -Property drivetype -eq 3 |
format-table deviceid,
#{n='GB Capacity';e={$_.size/1gb}},
#{n='GB Free';e={$_.freespace/1gb}},
#{n='%Free';e={($_.freespace/$_.size)*100}}
But adding this
| where {$_.'%Free' -gt 10}
Results in no output. In fact
| where {$_.'%Free' -gt 0}
Produces no results. Instead I have to use
| where {$_.'%Free' -lt 0}
Powershell thinks %Free is a negative number, I guess?
The problem is that you are piping Format-Table to anything. You should never use that except to output to the screen. Using Format-Table outputs everything as a format object, not whatever was piped into it. Instead use Select-Object to get what you need.
Get-WmiObject -Namespace root\cimv2 -Class win32_logicaldisk | where-object -Property drivetype -eq 3 |
Select-Object deviceid,
#{n='GB Capacity';e={$_.size/1gb}},
#{n='GB Free';e={$_.freespace/1gb}},
#{n='%Free';e={($_.freespace/$_.size)*100}}

Add two pipeline values together

How can I add the result of the following command together to get 20 as output instead of 2x 10?
gwmi Win32_processor -ComputerName SomeComputer | select-object -ExpandProperty NumberOfCores
You can use the Measure-Object cmdlet with the -Sum switch:
gwmi Win32_processor -ComputerName SomeComputer |
select-object -ExpandProperty NumberOfCores |
Measure-Object -Sum |
select -ExpandProperty Sum
Or if you want a hacky solution:
iex ((gwmi Win32_processor -ComputerName SomeComputer |
select-object -ExpandProperty NumberOfCores) -join '+')
This basically joins all numbers with a + to a string and then invokes that expression.