I have a list of PC's that i need to get the Physical Memory and the amount of memory slots available. I have a list of PC's in a text file and i am using the "get-content" cmdlet. This is what I have:
Get-WmiObject -Class Win32_PhysicalMemory -ComputerName (Get-Content "C:\TextFile.txt") | ForEach-Object {[math]::truncate($_.capacity / 1GB)}
When I run this, only the Memory total is displayed. My 2 questions are:
1) How can get the PC name to show up next to the corresponding number?
and
2) How can i add the total memory slots available to this as well?
Thank You!
DeviceLocator tells you the slot.
Example
$memoryBySlot = Get-CimInstance -Class Win32_PhysicalMemory | Foreach-Object {
[PSCustomObject] #{
CapacityGB = $_.Capacity /1GB
DeviceLocator = $_.DeviceLocator
ComputerName = $env:COMPUTERNAME
}
}
$memoryBySlot | Out-String
$memoryBySlot | Measure-Object -Property CapacityGB -Sum | select count, sum, property
Results
CapacityGB DeviceLocator ComputerName
---------- ------------- ------------
16 DIMM1 MYMACHINE
16 DIMM2 MYMACHINE
16 DIMM3 MYMACHINE
16 DIMM4 MYMACHINE
Count Sum Property
----- --- --------
4 64 CapacityGB
You can try something like that :
Get-Content "C:\TextFile.txt" | % {$a = (Get-CimInstance -ClassName Win32_PhysicalMemory -ComputerName $_ | Measure-Object -Sum -Property Capacity).Sum / (1024*1024*1024); [PSCUStOMOBJECT]#{"Computer"=$_;"MEM"=$a}} |export-csv 'file.csv'
Related
I have my first small project and I just started a PowerShell (total beginner).
We have three different shared C:\ drives and I need to output each disk storage info (e.g. total and free space) by using Powershell script.
Here is the script I made, but these three results are all the same even though they have different free spaces and total.
Can anyone please advise me on what is wrong with my ps script?
Plus, in the result, I don't want to display any other drives (e.g D and E) but only the C drive. How to do so?
[Script]
Set-Location -Path \\vm1\c$
Get-WmiObject -Class win32_logicaldisk | Format-Table DeviceId, #{n='Size'; e={[math]::Round($_.Size/1GB, 2)}}, #{n="FreeSpace"; e={[math]::Round($_.FreeSpace/1GB, 2)}}
Set-Location -Path \\vm2\c$
Get-WmiObject -Class win32_logicaldisk | Format-Table DeviceId, #{n='Size'; e={[math]::Round($_.Size/1GB, 2)}}, #{n="FreeSpace"; e={[math]::Round($_.FreeSpace/1GB, 2)}}
Set-Location -Path \\vm3\c$
Get-WmiObject -Class win32_logicaldisk | Format-Table DeviceId, #{n='Size'; e={[math]::Round($_.Size/1GB, 2)}}, #{n="FreeSpace"; e={[math]::Round($_.FreeSpace/1GB, 2)}}
[Result]
DeviceId Size FreeSpace
-------- ---- ---------
C: 473.95 114.22
D: 0 0
E: 0 0
DeviceId Size FreeSpace
-------- ---- ---------
C: 473.95 114.22
D: 0 0
E: 0 0
DeviceId Size FreeSpace
-------- ---- ---------
C: 473.95 114.22
D: 0 0
E: 0 0
Setting location to an UNC Path does not mean you're actually querying the win32_logicaldisk of that remote host, you need to use the -ComputerName Parameter to query the remote hosts information. Also worth noting, you should start using Get-CimInstance instead of Get-WmiObject (no longer available in newer versions of PowerShell).
As for displaying only the C drive, for this you can use -Filter. I've also added PSComputerName to your Format-Table returned properties so you can know which host the output belongs to.
$vms = 'vm1', 'vm2', 'vm3'
Get-CimInstance -Class win32_logicaldisk -Filter "DeviceID='C:'" -ComputerName $vms |
Format-Table #(
'PSComputerName'
'DeviceId'
#{ N='Size'; E={ [math]::Round($_.Size/1GB, 2) }}
#{ N='FreeSpace'; E={ [math]::Round($_.FreeSpace/1GB, 2) }}
)
Set-Location -Path \vm1\c$ does not work this way. it sets the default location on the filesystem for the current powershell session but does not influence get-wmiobject. to query remote computer you must use the parameter -computername.
you should use the cim cmdlets as they replace the wmi-object cmdlet. the parameter -computername supports an array as input so you only need to call get-wmiobject/get-ciminstance one time and if you only want to know about the C:\ drive, you can query for it:
$computers = #('vmName1','vmName2','nmName3')
Get-CimInstance -ComputerName $computers -Query "select freeSpace from win32_loogicaldoisk where deviceId='C:'" | select-object pscomputername,deviceid,freeSpace
I found the following PS command to list running processes sorted by CPU utilization:
Get-Counter -ErrorAction SilentlyContinue '\Process(*)\% Processor Time' |
Select-Object -ExpandProperty countersamples |
Select-Object -Property instancename, cookedvalue |
? {$_.instanceName -notmatch "^(idle|_total|system)$"} |
Sort-Object -Property cookedvalue -Descending |
Select-Object -First 10 |
ft InstanceName,#{L='CPU';E={($_.Cookedvalue/100/$env:NUMBER_OF_PROCESSORS).toString('P')}} -AutoSize
Below is the output, which appears it could be accurate, however while this ran my Antimalware Service Executable was using about 8% CPU. Why is this not showing up in the PowerShell output?
InstanceName CPU
------------ ---
msmpeng 0.39%
slack 0.19%
taskmgr 0.19%
pwsh 0.10%
todo 0.10%
dwm 0.10%
system 0.00%
creative cloud helper 0.00%
adobe desktop service 0.00%
adobeipcbroker 0.00%
Edit: The answer here gives similar results. Here is my adaptation of the answer (so it outputs it to a table instead of CSV)
$Cores = (Get-WmiObject -class win32_processor -Property numberOfCores).numberOfCores;
$LogicalProcessors = (Get-WmiObject –class Win32_processor -Property NumberOfLogicalProcessors).NumberOfLogicalProcessors;
$TotalMemory = (get-ciminstance -class "cim_physicalmemory" | % {$_.Capacity})
get-process -IncludeUserName | select #{Name="Time"; Expression={(get-date(get-date).ToUniversalTime() -uformat "%s")}},`
ID, StartTime, Handles,WorkingSet, PeakPagedMemorySize, PrivateMemorySize, VirtualMemorySize,`
#{Name="Total_RAM"; Expression={ ($TotalMemory )}},`
CPU,
#{Name='CPU_Usage'; Expression = { $TotalSec = (New-TimeSpan -Start $_.StartTime).TotalSeconds
[Math]::Round( ($_.CPU * 100 / $TotalSec) /$LogicalProcessors, 2) }},`
#{Name="Cores"; Expression={ ($Cores )}},`
#{Name="Logical_Cores"; Expression={ ($LogicalProcessors )}},`
UserName, ProcessName, Path | Sort-Object -Property CPU -Descending | Format-Table -Property ProcessName, CPU | Select -First 10
And here are the results:
ProcessName CPU
----------- ---
SearchIndexer 2898.21875
MsMpEng 1395.9375
System 1045
MsSense 612.359375
explorer 507.296875
OneDrive 467.296875
OUTLOOK 362.765625
SenseNdr 355.8125
After some tests, these results are actually worse. I ran a CPU intensive App and it shows up with the first (original) method, but it shows 1.5% even though Task Manager shows 25%. The second method, from the other SO answer, does not show the process at all.
I am trying to write a script that will get drive current drive space on our servers and return them to an output file.
Here is the script as of now:
$ServerName = Get-Content -Path "C:\Users\*****\Desktop\Testing Files\serverlist.txt"
Get-WmiObject Win32_LogicalDisk -ComputerName $ServerName -Filter DriveType=3 | Select-Object DeviceID, #{'Name'='Size (GB)'; 'Expression'={Expression'={[string]::Format('{0:NO}',[math]::truncate($_.size / 1GB))}}, #{'Name'='Freespace (GB)'; 'Expression'={[string]::Format('{0:NO}',[math]::truncate($_.freespace / 1GB))}}
Out-file "C:\users\xxxxxx\desktop\testing files\server space results.txt"
will not write to a text file; only displays results
The results display device ID, size (GB), freespace (GB) with no issues except one. Every drive is listed as C: and E: but does not split them up based on the device name so it is hard to tell which results go to which server. Below is a sample of the results of the script:
DeviceID Size (GB) Freespace (GB)
-------- --------- --------------
C: 58 13
E: 499 499
C: 79 30
E: 799 103
Any ideas?
You've got a few typos and/or syntax errors. Also if you want the Computer Name PowerShell adds the PSComputerName property:
$ServerName = Get-Content -Path "C:\Users\*****\Desktop\Testing Files\serverlist.txt"
Get-WmiObject Win32_LogicalDisk -ComputerName $ServerName -Filter DriveType=3 |
Select-Object PSComputerName,DeviceID,
#{'Name'='Size (GB)'; Expression = {[string]::Format('{0:N0}',[math]::truncate($_.size / 1GB))}},
#{'Name'='Freespace (GB)'; Expression = {[string]::Format('{0:N0}',[math]::truncate($_.freespace / 1GB))}} |
Out-file "C:\users\xxxxxx\desktop\testing files\server space results.txt"
Note: I prefer to use win32_Volume instead. Also you should think about using Get-CimInstance instead of Get-WMIObject. The latter is deprecated.
Update
Here's a slightly modified version. I typically use [Math]::Round() in these cases. It will keep the value numeric so it aligns right.
$ServerName = Get-Content -Path "C:\Users\*****\Desktop\Testing Files\serverlist.txt"
Get-WmiObject Win32_LogicalDisk -ComputerName $ServerName -Filter DriveType=3 |
Select-Object PSComputerName,DeviceID,
#{'Name'='Size (GB)'; Expression = { [Math]::Round( ($_.size / 1GB), 0 ) } },
#{'Name'='Freespace (GB)'; Expression = { [Math]::Round( ($_.freespace / 1GB), 0 ) } } |
Out-file "C:\temp\xxxxxx\desktop\testing files\server space results.txt"
I have tried the below command to get the memory usage of the computer but getting error as infinite or NaN.
$Totalsizemem=gwmi Win32_PhysicalMemory | Measure-Object -Property capacity -Sum | Foreach {"
{0:N2}" -f ([math]::round(($_.Sum / 1GB),2))}
gwmi -computername localhost Win32_Process | Sort WorkingSetSize -Descending | Select
Name,#{n="Memoryusage(%)";Expression ={[math]::round(($_.WorkingSetSize / 1GB),1) /
$Totalsizemem*100}} | Select -First 10 | Format-Table -AutoSize | Out-Default
The expected output is -
Name Memoryusage(%)
---- --------------
powershell_ise.exe 0.655737704918033
explorer.exe 0.655737704918033
explorer.exe 0.655737704918033
explorer.exe 0.655737704918033
but the output i'm getting -
Name Memoryusage(%)
---- --------------
powershell_ise.exe ∞
svchost.exe ∞
explorer.exe NaN
svchost.exe NaN
explorer.exe NaN
Does anyone know how to rectify this?
You keep rounding and formatting the intermediate results, sacrificing accuracy to the point where your data is meaningless.
Keep it simple:
$Totalsizemem = Get-WmiObject Win32_PhysicalMemory | Measure-Object -Property Capacity -Sum |Select -Expand Sum
Get-WmiObject Win32_Process |Sort WorkingSetSize -Descending |Select Name,#{Name='MemoryUsage(%)';Expression={$_.WorkingSetSize * 100 / $Totalsizemem}} -First 10
I found a script to check the available space on a remote computer. However I can't find how I can get the output in GB instead of B.
I don't know a lot about Powershell. Can somebody help me adjusting this code so I can see the available free disk space on a remote computer
$disk = Get-WmiObject Win32_LogicalDisk -ComputerName STR3598C -Filter "DeviceID='C:'" | Select-Object Size,FreeSpace
$disk.Size
$disk.FreeSpace
A possible way to achieve this could be to use the following:
gwmi win32_logicaldisk -ComputerName STR3598C -Filter "DeviceID='C:'" | Format-Table DeviceId, MediaType, #{n="Size";e={[math]::Round($_.Size/1GB,2)}},#{n="FreeSpace";e={[math]::Round($_.FreeSpace/1GB,2)}}
Expected output:
DeviceId MediaType Size FreeSpace
-------- --------- ---- ---------
C: 12 215.52 111.1
Another way is to store the results in a variable (like with your code example) and format that for output to screen and/or save it in a CSV file:
$computer = 'STR3598C'
$disk = Get-WmiObject Win32_LogicalDisk -ComputerName $computer -Filter "DeviceID='C:'" |
Select-Object #{Name = 'Computer'; Expression = {$_.PSComputerName}},
DeviceID, VolumeName,
#{Name = 'Size'; Expression = {'{0:N2}' -f ($_.Size / 1GB)}},
#{Name = 'FreeSpace'; Expression = {'{0:N2} GB' -f ($_.FreeSpace / 1GB)}}
# output on screen
$disk | Format-Table -AutoSize
# or save the output as CVS
$disk | Export-Csv -Path 'D:\disksize.csv' -NoTypeInformation
Output on screen
Computer DeviceID VolumeName Size FreeSpace
-------- -------- ---------- ---- ---------
STR3598C C: Systeem 232,79 GB 89,33 GB