I have a WMI query to get the memory usage on a remote server:
$w3wpresult = (get-wmiobject Win32_Process -filter "commandline like '%serviceoptimization%'" -computername $server -ErrorAction Stop| select ({$_.privatepagecount / 1gb})
$vmresult = (get-wmiobject Win32_Process -filter "commandline like '%serviceoptimization%'" -computername $server -ErrorAction Stop| select ({$_.virtualsize / 1gb}))
Output:
IP 21Aug2015 0939 #{$_.privatepagecount / 1gb=1.0206184387207} #{$_.virtualsize / 1gb=1.77864074707031}
IP 21Aug2015 0939 #{$_.privatepagecount / 1gb=0.945835113525391} #{$_.virtualsize / 1gb=1.72514343261719}
I do not want the #{$.privatepagecount / 1gb= part of the string.
I just want to see the numeric value for the memory.
How do I do this?
Any input is greatly appreciated thanks!
You can't use Select-Object with that type of scriptblock for a custom property. Instead, build it this way using a hash table and specifying a label and expression:
#{L='PrivatePageCountGB';E={$_.privatepagecount / 1gb}}
Putting it together to look like this:
$w3wpresult = get-wmiobject Win32_Process -filter "commandline like '%serviceoptimization%'" -computername $server -ErrorAction Stop|
select #{L='PrivatePageCountGB';E={$_.privatepagecount / 1gb}}
$vmresult = get-wmiobject Win32_Process -filter "commandline like '%serviceoptimization%'" -computername $server -ErrorAction Stop|
select #{L='VirtualSizeGB';E={$_.virtualsize / 1gb}}
If you only care about the value, then this would work as well.
$w3wpresult = (get-wmiobject Win32_Process -filter "commandline like '%serviceoptimization%'" -computername $server -ErrorAction Stop).privatepagecount /1GB
$vmresult = (get-wmiobject Win32_Process -filter "commandline like '%serviceoptimization%'" -computername $server -ErrorAction Stop).virtualsize/1GB
Related
I am using this PowerShell script below to find the memory usage of a Windows Server.
I would like to know if there is a simpler/cleaner way so I can quickly copy-paste to the problem server.
$ComputerMemory = Get-WmiObject -ComputerName $Server -Class win32_operatingsystem -ErrorAction Stop
$Memory = ((($ComputerMemory.TotalVisibleMemorySize - $ComputerMemory.FreePhysicalMemory)*100)/ $ComputerMemory.TotalVisibleMemorySize)
$RoundMemory = [math]::Round($Memory, 2)
$RoundMemory
A little bit shorter:
Gwmi win32_operatingsystem | % {
(($_.TotalVisibleMemorySize - $_.FreePhysicalMemory) * 100 /
$_.TotalVisibleMemorySize).ToString(".00")
}
Another approach using the newer Get-CimInstance cmdlet:
'{0:N2}' -f (Get-CimInstance -ComputerName $Server -ClassName Win32_OperatingSystem |
Select-Object #{Name = 'Memory'; Expression = {
(($_.TotalVisibleMemorySize - $_.FreePhysicalMemory)*100)/ $_.TotalVisibleMemorySize}
}).Memory
How can I write a quick 1-liner for write-host'ing an object property (let's say Name)? Here is the object I want to print the Name of ...
Get-WmiObject -Class win32_ComputerSystem -namespace "root\CIMV2"
I tried ...
write-host $_.name | Get-WmiObject -Class win32_ComputerSystem -namespace "root\CIMV2"
But this seems to still print all object properties. What can I do to fix this command?
You can use the -ExpandProperty parameter of the Select-Object cmdlet to retrieve just the computer name, then pipe that to Write-Host (formatted as multiple lines for readability):
Get-WmiObject -Class win32_ComputerSystem -namespace "root\CIMV2" `
| Select-Object -ExpandProperty 'Name' `
| Write-Host;
Alternatively, use the ForEach-Object cmdlet to get the Name property:
Get-WmiObject -Class win32_ComputerSystem -namespace "root\CIMV2" `
| ForEach-Object { $_.Name; } `
| Write-Host;
This is not a one-liner, but another approach similar to what you tried:
$computer = Get-WmiObject -Class win32_ComputerSystem -namespace "root\CIMV2";
Write-Host $computer.Name;
Note that since you only care about the Name property of Win32_ComputerSystem, it's a good idea to communicate that to Get-WmiObject using the -Property parameter so it doesn't bother returning information that will be discarded anyways:
Get-WmiObject -Class win32_ComputerSystem -namespace "root\CIMV2" -Property 'Name'
In addition to the answer from BACON, another option is this (needs PowerShell v3 or higher):
Write-Host (Get-WmiObject -Class win32_ComputerSystem -namespace "root\CIMV2").Name
I do the following to check for local drives/partitions on a remote computer:
Get-WmiObject -Class Win32_Share -ComputerName SERVERNAME -Filter "Description='Default share'"
but the command also returns CD-roms etc.
Is there a command to only return disk/partitions?
Get-WmiObject -Class Win32_LogicalDisk -Filter "DriveType=3" |
Foreach-Object {$_.DeviceID}
Try this:
Get-WMIObject Win32_DiskPartition -computername remotecomp |
ForEach-Object {
$info = #{}
$info.Disk = $_.DiskIndex
$info.Partition = $_.Index
$info.DriveLetter = $_.psbase.GetRelated('Win32_LogicalDisk') |
Select-Object -ExpandProperty DeviceID
New-Object PSObject -Property $info
}
$info # contains partions number and unit letter as hashtable
Get-WmiObject -query "Select * from Win32_DiskPartition" ... maybe?
I'm pulling my hair out here, because I just can't seem to get this to work, and I can't figure out how to google this issue. I'm running Powershell 2.0. Here's my script:
$computer_names = "server1,server2"
Write-Output "Invoke-Command -ComputerName $computer_names -ScriptBlock {
Get-WmiObject -Class Win32_LogicalDisk |
sort deviceid |
Format-Table -AutoSize deviceid, freespace
}"
Invoke-Command -ComputerName $computer_names -ScriptBlock {
Get-WmiObject -Class Win32_LogicalDisk |
sort deviceid |
Format-Table -AutoSize deviceid, freespace
}
The last command gives the error:
Invoke-Command : One or more computer names is not valid. If you are trying to
pass a Uri, use the -ConnectionUri parameter or pass Uri objects instead of
strings.
But when I copy the output of the Write-Output command to the shell and run that, it works just fine. How can I cast the string variable to something that Invoke-Command will accept? Thanks in advance!
Jamey and user983965 are correct, in that your declaration is wrong. However foreach here is not mandatory. If you just fix your array declaration like this, it will work:
$computer_names = "server1","server2"
Invoke-Command -ComputerName $computer_names -ScriptBlock {
Get-WmiObject -Class Win32_LogicalDisk |
sort deviceid |
Format-Table -AutoSize deviceid, freespace
}
You declared your array incorrectly. Put a comma between strings and pipe it to for-each like:
$computer_names = "server1", "server2";
$computer_names | %{
Write-Output "Invoke-Command -ComputerName $_ -ScriptBlock {
...snip
If you're getting an array of computers from active directory too - like this:
$computers = Get-ADComputer -filter {whatever}
Make sure you remember to select/expand the results.. like this:
$Computers= Get-ADComputer -filter * | Select-Object -ExpandProperty Name
Then...
Invoke-Command -ComputerName $Computers -ScriptBlock {Do Stuff}
have you tried:
$computer_names = "server1" , "server2"
foreach ($computer in $computer_names)
{
Write-Output "Invoke-Command -ComputerName $computer -ScriptBlock {
Get-WmiObject -Class Win32_LogicalDisk |
sort deviceid |
Format-Table -AutoSize deviceid, freespace
}"
Invoke-Command -ComputerName $computer -ScriptBlock {
Get-WmiObject -Class Win32_LogicalDisk |
sort deviceid |
Format-Table -AutoSize deviceid, freespace
}
}
I'm trying to call Get-WMIObject (gwmi) on multiple computers selected via Get-ADComputer as a background job.
My first attempt was
$job = Get-ADComputer -filter "name -like '*t90*'" | % { gwmi -computername $_.name -query "select name,username from win32_computersystem" -asjob -throttlelimit 10 }
However, since I'm calling gwmi once for each computer object returned, hundreds of background jobs are created, and I don't believe they're collectively heeding the ThrottleLimit.
Am I doing this right?
I know that gwmi can also accept an array for the computername attribute, as so:
$job = gwmi -computername "computer1","computer2","computer3" -query "select * from win32_computersystem" -asjob -throttlelimit 10
Doing it this way results in a single job rather than hundreds, since gwmi is only called once. Is that the way I should be doing it? And, if so, how do I feed the output of Get-ADComputer to gwmi as an array?
Thanks!
First get all computer names and pass them to the computerName parameter:
$cn = Get-ADComputer -filter "name -like '*t90*'" | select -expand name
$job = gwmi -computername $cn -query "select name,username from win32_computersystem" -asjob -throttlelimit 10