Error in foreach function in powershell - powershell

Below is the code snippet i tried but having an error because of it can anyone helpme in editing this one
$colItems4 = Get-WMIObject -class Win32_PhysicalMemory | Measure-Object -Property capacity -Sum |
foreach ($objItem4 in $colItems4 )
{
write-host "Total Physical Ram : " $objItem4.Sum
}

You already had it. You just added too much.
Gwmi win32_PhysicalMemory | Measure-Object -Property Capacity -Sum
And if you wanted to show only the sum then:
Gwmi win32_physcialmemory | measure-object -property Capacity -sum | select sum

$colItems4 = Get-WMIObject -class Win32_PhysicalMemory | Measure-Object -Property capacity -Sum
foreach ($objItem4 in $colItems4 )
{
write-host "Total Physical Ram : " $objItem4.Sum
}
Your code works fine. You just have an extra pipe at the end of your gwmi cmdlet.

$colItems4 = Get-WMIObject -class Win32_PhysicalMemory -computername $strComputer
$colItems5=$colItems4 | Measure-Object -Property capacity -Sum
foreach ($objItem4 in $colItems5)
{
write-host "Memory : " $colItems5.Sum
}
Will solve the problem :D

Related

Formatting multiple result sets together in powershell

Get-WmiObject -Class Win32_OperatingSystem -ComputerName (Get-Content "C:\Temp\Servers.txt") | SELECT-Object PSComputerName, #{Name="Memory (RAM in GB)";Expression={[Math]::Round($_.TotalVisibleMemorySize/1024/1024)}} | Format-Table
Get-WmiObject -Class Win32_logicaldisk -ComputerName (Get-Content "C:\Temp\Servers.txt") | Select-Object PSComputerName, DriveType, DeviceID, VolumeName, #{Name="Size";Expression={[math]::ceiling($_.Size /1GB)}} , #{Name="FreeSpace";Expression={[math]::ceiling($_.FreeSpace /1GB)}}, Compressed | where DriveType -eq 3 | Format-Table
Get-WmiObject -Class Win32_OperatingSystem -ComputerName (Get-Content "C:\Temp\Servers.txt")| Select-Object PSComputerName, BuildNumber, BuildType, Caption, CodeSet, OSArchitecture, SystemDrive, TotalVisibleMemorySize, Version | Format-Table
Get-WmiObject -Class win32_product -ComputerName (Get-Content "C:\Temp\Servers.txt") | Select-Object Name, Version, Vendor, InstallDate | Format-Table
Get-WmiObject -Class Win32_Service -ComputerName (Get-Content "C:\Temp\Servers.txt") | Select-Object PSComputerName, DisplayName, StartName, PathName, StartMode| where DisplayName -Like "*xyz*" |Format-Table
I have till now managed to piece together the above to get the information I need from serveral servers, however now I want to format it so that I can collate information for each server in a format that I can display
for eg.
Server : ABC
RAM : 64 GB
Number of Processors : 8
Disk :
Table of disk Sizes Etc
Any pointers would be appreciated
With all these properties, you would get a nested object array, which probably is easiest to view in JSON format.
I have changed all Get-WmiObject into the newer and faster Get-CimInstance cmdlets below
$result = Get-Content "C:\Temp\Servers.txt" | ForEach-Object {
# create an ordered hashtable to store the results for each server
$pcinfo = [ordered]#{}
# System info
$data = Get-CimInstance -ClassName Win32_ComputerSystem -ComputerName $_
$pcinfo['Computer'] = $data.PSComputerName
$pcinfo['Memory (RAM in GB)'] = '{0:N2}' -f ($data.TotalPhysicalMemory / 1GB)
# OS info
$data = Get-CimInstance -ClassName Win32_OperatingSystem -ComputerName $_
$pcinfo['BuildNumber'] = $data.BuildNumber
$pcinfo['BuildType'] = $data.BuildType
$pcinfo['Caption'] = $data.Caption
$pcinfo['CodeSet'] = $data.CodeSet
$pcinfo['OSArchitecture'] = $data.OSArchitecture
$pcinfo['SystemDrive'] = $data.SystemDrive
$pcinfo['TotalVisibleMemorySize'] = $data.TotalVisibleMemorySize
$pcinfo['Version'] = $data.Version
# Product info (array of objects)
$pcinfo['Products'] = Get-CimInstance -ClassName Win32_Product -ComputerName $_ |
Select-Object Name, Version, Vendor, InstallDate
# Local fixed disk info (array of objects)
$pcinfo['FixedDrives'] = Get-CimInstance -ClassName Win32_LogicalDisk -ComputerName $_ -Filter 'DriveType=3' |
Sort-Object DeviceID |
Select-Object DriveType, DeviceID, VolumeName,
#{Name="Size";Expression={"{0:N2} GB" -f ($_.Size / 1GB)}},
#{Name="FreeSpace";Expression={"{0:N2} GB" -f ($_.FreeSpace / 1GB)}},
Compressed
# Services info (array of objects)
$pcinfo['Services'] = Get-CimInstance -ClassName Win32_Service -ComputerName $_ |
Where-Object { $_.DisplayName -like '*Adobe*' } |
Select-Object DisplayName, StartName, PathName, StartMode
# convert the hashtable to PSObject and output
[PsCustomObject]$pcinfo
}
# output the whole structure as JSON for easier reading and optionally save it to file
$result | ConvertTo-Json -Depth 3 # | Set-Content -Path 'Path\To\Output.json' -Force

Powershell Newline Character is not working I tried `n "`n" '`n'

**I tried n "n" '`n'
Blockquote
**
GC D:\code\ServerList.txt | % {
$Comp = $_
#write-output "server Information"
If (Test-Connection $Comp -Quiet){
$Luser = (Get-WmiObject -class win32_process -Filter
"Name='Explorer.exe'" -ComputerName $Comp | % {$_.GetOwner().User} |
Sort-Object -Unique) -join ","
$Mem = GWMI -Class win32_operatingsystem -computername $COMP
New-Object PSObject -Property #{
"ServerInfo" = ""
Server = $Comp
"CPU usage" = "$((GWMI -ComputerName $COMP win32_processor
| Measure-Object -property LoadPercentage -Average).Average) %"
"Memory usage" = "$("{0:N2}" -f
((($Mem.TotalVisibleMemorySize - $Mem.FreePhysicalMemory)*100)/
$Mem.TotalVisibleMemorySize)) %"
"Total FreeSpace" = "$("{0:N2}" -f ((Get-WmiObject -Class
win32_logicaldisk -ComputerName $COMP -Filter "DriveType = '3'" |
Measure-Object -property FreeSpace -Sum).Sum /1GB)) GB"
"DiskSpace" = "$("{0:N2}" -f ((Get-WmiObject -Class
win32_logicaldisk -ComputerName $COMP -Filter "DriveType = '3'" |
Measure-Object -property Size -Sum).Sum /1GB)) GB"
"Comment" = ""
"logged Users" = $Luser
}
}
Else{
"" | Select #{N="Server";E={$Comp}},"CPU usage","Memory usage","Total
FreeSpace","logged Users","DiskSpace"
}
}| Select "ServerInfo",Server,"logged Users","CPU usage","Memory
usage","Total FreeSpace" ,"DiskSpace", "Comment" |
Export-Csv "D:\code\Diskncpu.csv" -nti –Append
output
desired output
"`r`n"
Needs to be in double quotes I believe.
Use [System.Environment]::NewLine to add new lines anywhere you need.
Having said that I formatted your code for clarity and executed against an array
#("MECDEVAPP01","MECDEVAPP01")| % {
$Comp = $_
#write-output "server Information"
If (Test-Connection $Comp -Quiet){
$Luser = (Get-WmiObject -class win32_process -Filter "Name='Explorer.exe'" -ComputerName $Comp | % {$_.GetOwner().User} | Sort-Object -Unique) -join ","
$Mem = GWMI -Class win32_operatingsystem -computername $COMP
New-Object PSObject -Property #{
"ServerInfo" = ""
Server = $Comp
"CPU usage" = "$((GWMI -ComputerName $COMP win32_processor | Measure-Object -property LoadPercentage -Average).Average) %"
"Memory usage" = "$("{0:N2}" -f ((($Mem.TotalVisibleMemorySize - $Mem.FreePhysicalMemory)*100)/ $Mem.TotalVisibleMemorySize)) %"
"Total FreeSpace" = "$("{0:N2}" -f ((Get-WmiObject -Class win32_logicaldisk -ComputerName $COMP -Filter "DriveType = '3'" | Measure-Object -property FreeSpace -Sum).Sum /1GB)) GB"
"DiskSpace" = "$("{0:N2}" -f ((Get-WmiObject -Class win32_logicaldisk -ComputerName $COMP -Filter "DriveType = '3'" | Measure-Object -property Size -Sum).Sum /1GB)) GB"
"Comment" = ""
"logged Users" = $Luser
}
}
Else{
"" | Select #{N="Server";E={$Comp}},"CPU usage","Memory usage","Total FreeSpace","logged Users","DiskSpace"
}
}| Select "ServerInfo",Server,"logged Users","CPU usage","Memory usage","Total FreeSpace" ,"DiskSpace", "Comment"|
Export-Csv "C:\Users\asarafian\Downloads\Diskncpu.csv" -nti –Append
The csv file is like this
"ServerInfo","Server","logged Users","CPU usage","Memory usage","Total FreeSpace","DiskSpace","Comment"
"","MECDEVAPP01","","7 %","70,24 %","203,97 GB","278,36 GB",""
"","MECDEVAPP01","","0 %","70,25 %","203,97 GB","278,36 GB",""
which is what I would expect from a conversion of a recordset (that's what you are building with all those pipes) into a csv.
I you want to product a formatted text then you cant use csv or you need to combine elements of it.
Try using `r`n for a new line. It needs the new line and carriage return to work.
If I understand you correctly you want a row to appear with a newline character, but instead you get the `r`n litteral characters or anything you try to throw at it.
Minimal testcase I can come up with to reproduce this problem:
> function paste ($separator = '`r`n') {$($input) -join $separator}
> & { echo foo; echo bar; echo baz; } | paste
foo`r`nbar`r`nbaz
Expceted result was
foo
bar
baz
How do you get actual newlines as output instead of literal `r`n? Super simple, just use the suggested answer!
> function paste ($separator = "`r`n") {$($input) -join $separator}
> & { echo foo; echo bar; echo baz; } | paste
foo
bar
baz
Or, if you do not like magic strings:
function paste ($separator = [System.Environment]::NewLine) {$($input) -join $separator}
PS D:\Temp\specs\ProRail.TrackChanges.Specs.Features> & { echo foo; echo bar; echo baz; } | paste
foo
bar
baz

How to extract server information

Objective: How to extract server information?
For each server name listed in servers.txt, I would like to get the following information (in this format):
Server name, IP Address, OS name, Total Physical Memory, Processors, each drive letter and size, System Model
Comma separated and new line for each server.
Below is my PowerShell code. Can your guys give a hint on why this does not work? Also why I get an error with New-Object statement?
foreach ($ComputerName in (Get-Content -Path .\servers.txt)) {
$HashProps = #{
'tHostname' = Get-WmiObject Win32_Computersystem -ComputerName $ComputerName | Select-Object -ExpandProperty Name
'tIP' = [System.Net.Dns]::GetHostAddresses($computername)
'tOS' = Get-WmiObject -ComputerName $ComputerName -Class Win32_OperatingSystem | Select-Object -ExpandProperty Caption
'tMemory' = Get-WmiObject Win32_PhysicalMemory | Measure-Object -Property capacity -Sum | foreach { "$("{0:n2}" -f ( $_.Sum/1GB ) )" }
'tcpu' = Get-WmiObject Win32_processor | Select-Object name, numberofcores
'tDisks' = Get-WmiObject Win32_LogicalDisk | foreach { "$($_.DeviceID) $("{0:n2}" -f ( $_.Size/ 1GB ) )" }
'tsysmodel' = Get-Wmiobject Win32_computersystem | Select-Object model
}
New-Object -TypeName psObject -Property $HashProps |
ConvertTo-Csv -NoTypeInformation | Out-File -Append .\output.csv
}
I am open for a other approach, if this is easier.
Have you verified that each of those lines actually return what you want?
I just threw this into the ISE and it works fine:
$f = gwmi win32_computersystem | select name,model,totalphysicalmemory
$hash = #{
'name' = $f.name
'model' = $f.model
'memory' = $("{0:n2}" -f ( $f.totalphysicalmemory/1GB ) )
}
New-Object -TypeName psobject -Property $hash | ConvertTo-Csv -NoTypeInformation | Out-File -Append .\test.csv
Also, if you want the properties to appear in a specific order in the CSV, it will take some additional magic, otherwise they're put in alphabetically.
A little bit pimped, maybe this will help you:
$Servers = Foreach ($ComputerName in (Get-Content -Path .\Servers.txt)) {
$CS = Get-WmiObject Win32_ComputerSystem -ComputerName $ComputerName
$OS = Get-WmiObject Win32_OperatingSystem -ComputerName $ComputerName
$PM = Get-WmiObject Win32_PhysicalMemory -ComputerName $ComputerName
$PR = Get-WmiObject Win32_processor -ComputerName $ComputerName
$LD = Get-WmiObject Win32_LogicalDisk -ComputerName $ComputerName
$IP = [System.Net.Dns]::GetHostAddresses($ComputerName)
[PSCustomObject]#{
ServerName = $CS | Select-Object -ExpandProperty Name
IPAddress = $IP | Select-Object -ExpandProperty IPAddressToString
OS = $OS | Select-Object -ExpandProperty Caption
Memory = $PM | Measure-Object -Property Capacity -Sum | foreach { "$("{0:n2}" -f ( $_.Sum/1GB ) )" }
CPU = $PR | Select-Object Name, NumberOfCores
Disks = $LD | foreach { "$($_.DeviceID) $("{0:n2}" -f ( $_.Size/ 1GB ) )" }
Model = $CS | Select-Object -ExpandProperty Model
}
}
$File = Join-Path $env:TEMP 'Ouptut.csv'
$Servers | Export-Csv -Path $File -NoTypeInformation -Delimiter ';'
Start-Process $File

PowerShell - Get Average Memory Usage of Server

I am running an instance of Windows Server 2012 R2 and would like to get the average memory usage of my server.
To get the CPU usage, I use
Get-WmiObject win32_processor | select LoadPercentage |fl
and to get the average CPU usage, I have
Get-WmiObject win32_processor | Measure-Object -property LoadPercentage -Average | Select Average
How do I do the same thing with memory usage?
You want the Win32_OperatingSystem namespace, and it's TotalVisibleMemorySize (physical memory), FreePhysicalMemory, TotalVirtualMemorySize, and FreeVirtualMemory properties.
Get-WmiObject win32_OperatingSystem |%{"Total Physical Memory: {0}KB`nFree Physical Memory : {1}KB`nTotal Virtual Memory : {2}KB`nFree Virtual Memory : {3}KB" -f $_.totalvisiblememorysize, $_.freephysicalmemory, $_.totalvirtualmemorysize, $_.freevirtualmemory}
That will spit back:
Total Physical Memory: 4079572KB
Free Physical Memory : 994468KB
Total Virtual Memory : 8157280KB
Free Virtual Memory : 3448916KB
I'm sure you can do the math if you want to get Used instead of Free.
Edit: Your CPULoad Average isn't really an average of anything. Case in point:
For($a=1;$a -lt 30;$a++){
Get-WmiObject win32_processor|ForEach{
[pscustomobject][ordered]#{
'Average' = $_ | Measure-Object -property LoadPercentage -Average | Select -expand Average
'Current' = $_ | select -expand LoadPercentage
}
}
Start-Sleep -Milliseconds 50
}
Results:
Average CPU Load
------- --------
2 2
1 1
1 1
1 1
1 1
5 5
1 1
1 1
0 0
1 1
1 1
1 1
2 2
4 4
0
1 1
7 7
24 24
1 1
If you want an average over a period of time you could use performance counters
### Get available memory in MB ###
$interval = 1 #seconds
$maxsamples = 5
$memorycounter = (Get-Counter "\Memory\Available MBytes" -maxsamples $maxsamples -sampleinterval $interval |
select -expand countersamples | measure cookedvalue -average).average
### Memory Average Formatting ###
$freememavg = "{0:N0}" -f $memorycounter
### Get total Physical Memory & Calculate Percentage ###
$physicalmemory = (Get-WMIObject -class Win32_PhysicalMemory | Measure-Object -Property capacity -Sum).Sum / 1mb
$physicalmemory - $freememavg
Function Get-ADtop {
[CmdletBinding()]
param(
[String]$ComputerName,
[String]$Sort = "none",
[String]$BaseDN = "OU=systems,DC=domain,DC=com", # Edit Default Base DN
[String]$SampleTime = 2
)
If ($ComputerName) {
$Computers = $ComputerName
} else {
$Computers = Get-ADComputer -Filter * -Properties * -SearchBase $BaseDN -EA SilentlyContinue | % {$_.Name}
}
$DataSet = #()
$Targets = #()
ForEach ($Comp in $Computers) {
If (Test-Connection -ComputerName $Comp -Count 1 -Quiet -TimeToLive 1 -EA SilentlyContinue) {
If (!(Get-WmiObject -ComputerName $Comp win32_OperatingSystem -EA SilentlyContinue)) { break }
$Targets += $Comp
}
}
$CompCount = $Computers | Measure-Object | % {$_.Count}
$DeadCount = $CompCount - ($Targets | Measure-Object | % {$_.Count})
If (!($DeadCount -eq 0)) {
Write-Host "`n$DeadCount unavailable computers removed"
}
Write-Host "`nGathering realtime CPU/MEM/DISK Usage data from $CompCount computers..."
ForEach ($Comp in $Targets) {
$proc = (Get-WmiObject -ComputerName $Comp -class win32_processor -EA SilentlyContinue | Measure-Object -property LoadPercentage -Average | Select Average | % {$_.Average / 100}).ToString("P")
$mem = Get-WmiObject -ComputerName $Comp win32_OperatingSystem -EA SilentlyContinue
$mem = (($mem.TotalVisibleMemorySize - $mem.FreePhysicalMemory) / $mem.TotalVisibleMemorySize).ToString("P")
$disk = Get-WmiObject -ComputerName $Comp -class Win32_LogicalDisk -filter "DriveType=3" -EA SilentlyContinue
$disk = (($disk.Size - $disk.FreeSpace) / $disk.Size).ToString("P")
$Info = [pscustomobject]#{
'Computer' = $Comp
'CPU Usage' = $proc
'MEM Usage' = $mem
'Disk Usage' = $disk
}
$DataSet += Add-Member -InputObject $Info -TypeName Computers.CPU.Usage -PassThru
}
Switch ($Sort) {
"none" { $DataSet }
"CPU" { $DataSet | Sort-Object -Property "CPU Usage" -Descending }
"MEM" { $DataSet | Sort-Object -Property "MEM Usage" -Descending }
"DISK" { $DataSet | Sort-Object -Property "DISK Usage" -Descending }
}
}
More info here GitHub Gist Link

Powershell - helping with our CMDB Issue - Opinions?

recently I took it upon myself to learn Powershell. It was a rough 2 weeks and a lot of reading but I'm getting better and better. I had some pressure at work to help with correcting our CMDB. We are about 7 months away from having a true Depolyment/Asset Management system in place. We have many reasons for relying on Powershell right now and we're trying to clean up a mess before we get the management system in. Anyway, I created a script that gets a lot of information for us. We have about 3000 objects/pcs and we need as much info as possible. Anyway, I created a script. So far it works well but I wanted some opinions from the experts or any advice. I feel like I did a decent job putting this together with only 2 weeks experiance but I really want to know what others think.
One thing I noticed: Windows 7 Boxes with IE9 and Up do not return a value for IE Version. Anyone know why?
Please see my code below:
Set-QADPSSnapinSettings -defaultSizeLimit 0
$FullPCList = (Get-QADComputer -SearchRoot $ou | Sort Name | select -expand name)
foreach ($computer in $FullPCList) {
ping -n 2 $computer >$null
if($lastexitcode -eq 0) { $Online = "Yes" } else { $Online = "No" }
$PCInfo = (Get-WmiObject -ComputerName $computer -Class Win32_ComputerSystem -ErrorAction SilentlyContinue)
$WinInfo = (Get-WmiObject -ComputerName $computer -Class Win32_OperatingSystem -ErrorAction SilentlyContinue)
$ram = ((Get-WmiObject -ComputerName $computer -Class Win32_PhysicalMemory -ErrorAction SilentlyContinue | Measure-Object Capacity -Sum).Sum / 1MB)
$bios = (Get-WmiObject -ComputerName $computer -Class Win32_Bios -ErrorAction SilentlyContinue)
$ie = (Get-Wmiobject -ComputerName $computer -namespace “root\CIMV2\Applications\MicrosoftIE” -query “select version from MicrosoftIE_Summary” -ErrorAction SilentlyContinue)
$freespace = ((Get-WmiObject -ComputerName $computer -Class Win32_LogicalDisk | Select Freespace | Measure-object Freespace -Sum).Sum / 1GB)
#Start uptime check
$LastBootUpTime = $WinInfo.ConvertToDateTime($WinInfo.LastBootUpTime)
$Time = (Get-Date) - $LastBootUpTime
$formattime = '{0:00}:{1:00}:{2:00}' -f $Time.Days, $Time.Hours, $Time.Minutes
#End Uptime Check
if ($WinInfo.Caption -match "Windows 7") {
$name = (Get-ChildItem -Path "\\$Computer\C$\Users" -Exclude "*Service*","*admin*","*Public*","*ffodero*","*jgalli*","*jwalters*","*frochet*" | Sort-Object LastAccessTime -Descending | Select-Object Name -First 1).Name
$loggedintime = (Get-ChildItem -Path "\\$Computer\C$\Users" -Exclude "*Service*","*admin*","*Public*","*ffodero*","*jgalli*" | Sort-Object LastAccessTime -Descending | Select-Object LastAccessTime -First 1).LastAccessTime
}
if ($WinInfo.Caption -match "Windows XP") {
$name = (Get-ChildItem -Path "\\$Computer\C$\Documents and Settings" -Exclude "*Service*","*admin*","*Public*" | Sort-Object LastAccessTime -Descending | Select-Object Name -First 1).Name
$loggedintime = (Get-ChildItem -Path "\\$Computer\C$\Documents and Settings" -Exclude "*Service*","*admin*","*Public*" | Sort-Object LastAccessTime -Descending | Select-Object LastAccessTime -First 1).LastAccessTime
}
$table = #{
Model = $PCInfo.Model
IEVersion = $ie.Version
Serial = $Bios.SerialNumber
Memory = $ram
DriveFreeSpaceGB = $freespace
Manufacturer = $PCInfo.Manufacturer
OSName = $WinInfo.Caption
Computer = $computer
Uptime = $formattime
LastloggedinUser = $name
LastLoggedinDate = $loggedintime
LoggedOnDuringScan = $PCInfo.Username
ServicePack = $WinInfo.ServicePackMajorVersion
Online = $Online
}
New-Object PSObject -Property $table | Export-Csv C:\logs\mother.csv -NoTypeInformation -Append
}
The namespace root\CIMV2\Applications\MicrosoftIE has been removed starting with Windows Vista (see note at the end of the blog post). You should be able to read the version number from the registry, though:
$hive = [UInt32]'0x80000002'
$key = 'SOFTWARE\Microsoft\Internet Explorer'
$reg = [WMIClass]"\\$computer\root\default:StdRegProv"
$ieVersion = $reg.GetStringValue($hive, $key, 'Version').sValue