Could you help me combine these three scripts to a format that's like this
ComputerName CPUUsageAverage MemoryUsage C PercentFree
xxx 12 50% 30%
The way I execute this is:
Get-content '.\servers.txt' | Get-CPUusageAverage
Here are the scripts:
CPU
Function Get-CPUusageAverage
{
$input|Foreach-Object{Get-WmiObject -computername $_ win32_processor | Measure-Object -property LoadPercentage -Average | Select Average}
}
Memory
Function get-MemoryUsage
{
$input|Foreach-Object{
gwmi -Class win32_operatingsystem -computername $_ |
Select-Object #{Name = "MemoryUsage"; Expression = { “{0:N2}” -f ((($_.TotalVisibleMemorySize - $_.FreePhysicalMemory)*100)/ $_.TotalVisibleMemorySize) }
}
}
}
C PercentFree
Function get-CPercentFree
{
$input|ForEach-Object{
Get-WmiObject -Class win32_Volume -ComputerName $_ -Filter "DriveLetter = 'C:'" |
Select-object #{Name = "C PercentFree"; Expression = { “{0:N2}” -f (($_.FreeSpace / $_.Capacity)*100) } }
}
}
First I would avoid using $input. You can just combine the queries into single function that then outputs a pscustomobject with the data for each computer e.g.:
function Get-ComputerStats {
param(
[Parameter(Mandatory=$true, Position=0,
ValueFromPipeline=$true, ValueFromPipelineByPropertyName=$true)]
[ValidateNotNull()]
[string[]]$ComputerName
)
process {
foreach ($c in $ComputerName) {
$avg = Get-WmiObject win32_processor -computername $c |
Measure-Object -property LoadPercentage -Average |
Foreach {$_.Average}
$mem = Get-WmiObject win32_operatingsystem -ComputerName $c |
Foreach {"{0:N2}" -f ((($_.TotalVisibleMemorySize - $_.FreePhysicalMemory)*100)/ $_.TotalVisibleMemorySize)}
$free = Get-WmiObject Win32_Volume -ComputerName $c -Filter "DriveLetter = 'C:'" |
Foreach {"{0:N2}" -f (($_.FreeSpace / $_.Capacity)*100)}
new-object psobject -prop #{ # Work on PowerShell V2 and below
# [pscustomobject] [ordered] #{ # Only if on PowerShell V3
ComputerName = $c
AverageCpu = $avg
MemoryUsage = $mem
PercentFree = $free
}
}
}
cat '.\servers.txt' | Get-ComputerStats | Format-Table
How about:
cat '.\servers.txt' | % {select -property #{'n'='CPUUsageAverage';'e'={$_ | Get-CPUUsageAverage}},#{'n'='Memory Usage';'e'={$_ | Get-MemoryUsage}},#{'n'=C PercentFree';'e'={$_ | Get-CPercentFree}}}
Apologies above my previous post (Edited this), here's a script I am using to get the average of CPU, Mem, and C Drive free space which generate to an HTML file
$ServerListFile = "D:\serverList.txt"
$ServerList = Get-Content $ServerListFile -ErrorAction SilentlyContinue
$Result = #()
ForEach($computername in $ServerList)
{
$AVGProc = Get-WmiObject -computername $computername win32_processor |
Measure-Object -property LoadPercentage -Average | Select Average
$OS = gwmi -Class win32_operatingsystem -computername $computername |
Select-Object #{Name = "MemoryUsage"; Expression = {“{0:N2}” -f ((($_.TotalVisibleMemorySize - $_.FreePhysicalMemory)*100)/ $_.TotalVisibleMemorySize) }}
$vol = Get-WmiObject -Class win32_Volume -ComputerName $computername -Filter "DriveLetter = 'C:'" |
Select-object #{Name = "C PercentFree"; Expression = {“{0:N2}” -f (($_.FreeSpace / $_.Capacity)*100) } }
$result += [PSCustomObject] #{
ServerName = "$computername"
CPULoad = "$($AVGProc.Average)%"
MemLoad = "$($OS.MemoryUsage)%"
CDrive = "$($vol.'C PercentFree')%"
}
$Outputreport = "<HTML><TITLE> Server Health Report </TITLE>
<BODY background-color:peachpuff>
<font color =""#99000"" face=""Microsoft Tai le"">
<H2> Server Health Report </H2></font>
<Table border=1 cellpadding=0 cellspacing=0>
<TR bgcolor=gray align=center>
<TD><B>Server Name</B></TD>
<TD><B>Avrg.CPU Utilization</B></TD>
<TD><B>Memory Utilization</B></TD>
<TD><B>Drive C Free Space</B></TD>
</TR>"
Foreach($Entry in $Result)
{
if(($Entry.CpuLoad) -or ($Entry.memload) -ge "80")
{
$Outputreport += "<TR bgcolor=white>"
}
else
{
$Outputreport += "<TR>"
}
$Outputreport += "<TD>$($Entry.Servername)</TD><TD align=center>$($Entry.CPULoad)</TD><TD align=center>$($Entry.MemLoad)</TD><TD align=center>$($Entry.CDrive)</TD></TR>"
}
$Outputreport += "</Table></BODY></HTML>"
}
$Outputreport | out-file "D:\Result $(Get-Date -Format yyy-mm-dd-hhmm).htm"
Related
I have following script, i want to get each users details of ram and cpu utilization separately in csv file. but from this script i am getting all users details in a single line instead of individually user based resources utilization details in csv file.
This is my Powershell code
GC c:\List.txt | % {
$xl = New-Object -ComObject "Excel.Application"
$xl.Visible = $true
$xl.DisplayAlerts = $false #for debugging, no prompts to save, etc.
$ConvertToGB = (1024 * 1024 * 1024)
$wkbk = $xl.Workbooks.Add()
$sheet = $wkbk.WorkSheets.Item(1)
$sheet.Name = "Transposed"
$Comp = $_
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 #{
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)) %"
"DiskSpace" = "$("{0:N2}" -f (Get-WmiObject -Class win32_logicaldisk -ComputerName $COMP -Filter "DriveType = 3"| Select-Object "Size","FreeSpace"))"
#$Comp = ($disk.Size / $ConvertToGB),($disk.FreeSpace / $ConvertToGB)
"logged_Users" = $Luser
}
}
Else {
}
$results = Get-Service -Name *bits*| Select Server #,"CPU usage","Memory usage","DiskFreeSpace","logged Users"
$column = 1
$row = 1
foreach ($psRow in $results) {
foreach ($item in $psRow.PSObject.Properties) {
$sheet.Cells.Item($row, $column) = $item.Name
$column++
#$sheet.Cells.Item($row, $column) = $item."CPU","Memory_Usage","DiskSpace","logged_Users"
$row++
$column--
}
} }
$obj =New-Object PSObject -Property #{
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)) %"
"DiskSpace" = Get-WmiObject -Class win32_logicaldisk -ComputerName $COMP -Filter "DriveType = 3"| Select-Object "Size","FreeSpace"
#$Comp = ($disk.Size / $ConvertToGB),($disk.FreeSpace / $ConvertToGB)
"logged_Users" = $Luser
}
Write-Output "DiskSpace, $($obj.DiskSpace.Size), $($obj.DiskSpace.FreeSpace)"
Write-Output "Server, $($obj.Server)"
Write-Output "Memory_Usage, $($obj.Memory_Usage)"
Write-Output "logged_Users, $($obj.logged_Users)"
Write-Output "CPU_Usage, $($obj.CPU_Usage)"
$obj | ConvertTo-Csv
These are the results i am getting
Memory_Usage : 91.90 %
CPU_Usage : 99
Server : 127.0.0.1
logged_Users : user1,user2,user3,userA
DiskSpace : {#{Size=718642417664; FreeSpace=317923561472}, #{Size=214747312128; FreeSpace=182724562944}, #{Size=26507997184; FreeSpace=3710320640},
#{Size=1099511627776; FreeSpace=989560467456}}
I need this type of result in csv
logged users | Memory Usage in MB | CPU Usage % |
User1 25300 8
User2 33658 15
User3 48793 7
UserA 23564 5
why don't you use select-object? I can't test it b/c your script doesn't have the full code for me to test it, but it would be a little something like:
get-psdrive | Where Free* | Select-Object Name, #{Name='UsedGB'; Expression={$_.Used/1GB}}, #{Name='FreePerc'; Expression={'{0:p0}' -f((($_.Used)/1GB) / (($_.Free + $_.Used)/1GB))}}, #{Name='TotalSize'; Expression={($_.Free + $_.Used)/1GB}}
Result:
Name UsedGB FreePerc TotalSize
---- ------ -------- ---------
A 192.771030426025 81% 238.473628997803
C 336.458614349365 36% 930.742183685303
D 7043.1279296875 95% 7452.00390625
E 110.902645111084 47% 238.473628997803
You can use this to build the table you want.
From there, to export it to csv; I would assume you can export it with a pipe follow by export-csv -path (Destination + file name) -NoTypeInformation
I am new to PowerShell and am struggling to write a script to export the UserFriendlyName (see the code below) for three monitors. Here is what I have so far:
$monitors = Get-WmiObject -Namespace root\wmi -Class wmiMonitorID
Get-CimInstance -Namespace root\wmi -ClassName wmimonitorid -ComputerName $ComputerName |
foreach {
$Object = New-Object PSObject -Property #{
MonitorName = ($monitors.UserFriendlyName -notmatch '^0$' | foreach {[char]$_}) -join ""
MonitorSerial = ($monitors.serialnumberid -notmatch '^0$' | foreach {[char]$_}) -join ""
}
}
$Object | Select MonitorName,MonitorSerial
$Object | Export-Csv -append -force /Computer.csv -NoTypeInformation
The result that I am getting:
MonitorName MonitorSerial
----------- -------------
27B1DELL P2717HDELL P2717H GUHJBHA018695YKNFG6CQAGLLYKNFG71KAPTL
I would like to have each monitor name and serial number under their own column (Monitor 1, Monitor 2, Monitor 3 and the same for serial number) but the values are together. Any help is much appreciated.
I am hoping to have the above incorporated with this:
$computerSystem = Get-CimInstance CIM_ComputerSystem
$computerBIOS = Get-CimInstance CIM_BIOSElement
$computerOS = Get-CimInstance CIM_OperatingSystem
$computerCPU = Get-CimInstance CIM_Processor
$computerHDD = Get-CimInstance Win32_LogicalDisk -Filter "DeviceID = 'C:'"
Get-CimInstance -Namespace root\wmi -ClassName wmimonitorid -ComputerName $ComputerName |
foreach {
$Object = New-Object PSObject -Property #{
"Computer Name" = $computerSystem.Name
"Operating System" = $computerOS.caption + ", Service Pack: " + $computerOS.ServicePackMajorVersion
"Manufacturer" = $computerSystem.Manufacturer
"Model" = $computerSystem.Model
"Serial Number" = $computerBIOS.SerialNumber
"CPU" = $computerCPU.Name
"HDD Capacity" = "{0:N2}" -f ($computerHDD.Size/1GB) + "GB"
"RAM" = "{0:N2}" -f ($computerSystem.TotalPhysicalMemory/1GB) + "GB"
"User logged In" = $computerSystem.UserName
}
}
$Object | Export-Csv -append -force /Computer.csv -NoTypeInformation
Something does not seem right with your code. You should be adding each monitor to an array or a list.
$monitors = Get-WmiObject -Namespace root\wmi -Class wmiMonitorID
$allMonitors = #()
Get-CimInstance -Namespace root\wmi -ClassName wmimonitorid -ComputerName $ComputerName |
foreach {
$Object = [PSCustomObject]#{
MonitorName = ($monitors.UserFriendlyName -notmatch '^0$' | foreach {[char]$_}) -join ""
MonitorSerial = ($monitors.serialnumberid -notmatch '^0$' | foreach {[char]$_}) -join ""
}
$allMonitors += $Object
}
$allMonitors | Select MonitorName,MonitorSerial
$allMonitors | Export-Csv -append -force /Computer.csv -NoTypeInformation
I have the below PowerShell script which shows the remote servers CPU/Disk/Memory health check.
It is not giving the output in HTML format and I am sending it to my email id with SMTP option. It is all working fine.
Current Output:
Along with the HTML output I want this output to be saved in a CSV file as well so that I can load it into Teradata using MLOAD.
Please help me to get output in a CSV file.
How can we load the data in CSV file to Teradata, can this be done using powershell or batch?
Code:
$ServerListFile = "C:\Users\HOSDUM01\Desktop\Auto\Server_health_check\list.txt"
$ServerList = Get-Content $ServerListFile -ErrorAction SilentlyContinue
$Result = #()
ForEach ($computername in $ServerList) {
$AVGProc = Get-WmiObject -computername $computername win32_processor |
Measure-Object -property LoadPercentage -Average | Select Average
$OS = gwmi -Class win32_operatingsystem -computername $computername |
Select-Object #{Name = "MemoryUsage"; Expression = {“{0:N2}” -f ((($_.TotalVisibleMemorySize - $_.FreePhysicalMemory) * 100) / $_.TotalVisibleMemorySize) }}
$vol = Get-WmiObject -Class win32_Volume -ComputerName $computername -Filter "DriveLetter = 'C:'" |
Select-object #{Name = "C PercentFree"; Expression = {“{0:N2}” -f (($_.FreeSpace / $_.Capacity) * 100) } }
$vol2 = Get-WmiObject -Class win32_Volume -ComputerName $computername -Filter "DriveLetter = 'E:'" |
Select-object #{Name = "E PercentFree"; Expression = {“{0:N2}” -f (($_.FreeSpace / $_.Capacity) * 100) } }
$vol3 = Get-WmiObject -Class win32_Volume -ComputerName $computername -Filter "DriveLetter = 'F:'" |
Select-object #{Name = "F PercentFree"; Expression = {“{0:N2}” -f (($_.FreeSpace / $_.Capacity) * 100) } }
$result += [PSCustomObject] #{
ServerName = "$computername"
CPULoad = "$($AVGProc.Average)%"
MemLoad = "$($OS.MemoryUsage)%"
CDrive = "$($vol.'C PercentFree')%"
EDrive = "$($vol2.'E PercentFree')%"
FDrive = "$($vol3.'F PercentFree')%"
}
$Outputreport = "<HTML><TITLE> Server Health Report </TITLE>
<BODY background-color:peachpuff>
<font color =""#99000"" face=""Microsoft Tai le"">
<H2> Server Health Report </H2></font>
<Table border=1 cellpadding=0 cellspacing=0>
<TR bgcolor=Cyan align=center>
<TD><B>EP_Server_Name</B></TD>
<TD><B>CPU_Utilizied</B></TD>
<TD><B>Memory_Utilized</B></TD>
<TD><B>C_Drive_Free_Percentage</B></TD>
<TD><B>E_Drive_Free_Percentage</B></TD>
<TD><B>F_Drive_Free_Percentage</B></TD></TR>"
Foreach ($Entry in $Result) {
if (($Entry.CpuLoad) -ge "80" -or ($Entry.memload) -ge "80" -or ($Entry.Cdrive) -le "20" -or ($Entry.Edrive) -le "20" -or ($Entry.Fdrive) -le "20") {
$Outputreport += "<TR bgcolor=red>"
}
else {
$Outputreport += "<TR bgcolor=green>"
}
$Outputreport += "<TD>$($Entry.Servername)</TD><TD align=center>$($Entry.CPULoad)</TD><TD align=center>$($Entry.MemLoad)</TD><TD align=center>$($Entry.Cdrive)</TD><TD align=center>$($Entry.Edrive)</TD><TD align=center>$($Entry.Fdrive)</TD></TR>"
}
$Outputreport += "</Table></BODY></HTML>"
}
$Outputreport | out-file C:\Users\HOSDUM01\Desktop\Auto\Server_health_check\Test.htm
#Invoke-Expression C:\Users\HOSDUM01\Desktop\Auto\Server_health_check\Test.htm
##Send email functionality from below line, use it if you want
$smtpServer = "Random"
$smtpFrom = "test#test.com"
$smtpTo = "test#test.com"
$messageSubject = "Servers Health report"
$message = New-Object System.Net.Mail.MailMessage $smtpfrom, $smtpto
$message.Subject = $messageSubject
$message.IsBodyHTML = $true
$message.Body = "<head><pre>$style</pre></head>"
$message.Body += Get-Content C:\Users\HOSDUM01\Desktop\Auto\Server_health_check\test.htm
$smtp = New-Object Net.Mail.SmtpClient($smtpServer)
$smtp.Send($message)
As $result already contains the info you want in the csv, it can just be piped to Export-Csv
Simply add this line at the end of your script:
$result | Export-Csv -Path C:\folder\health_check.csv -NoTypeInformation
Not used Teradata but there was already a question on csv import: How to load data from a csv file into a table using Teradata Studio
All you need to do is, append to your script:
$Result | Export-Csv "C:\Users\HOSDUM01\Desktop\Auto\Server_health_check\Test.csv" -NoType
or whatever path you'd like to store the file
EDIT Reworked the script out of interrest.
Streamlined path usage
Inserted function DriveFreePercent and removed intermediate (unneccessary) variables.
moved the html creation outside of the foreach
Sample Csv file
"ServerName","CPULoad","MemLoad","CDrive","EDrive","FDrive"
"HP-G1610","4","32,61","94,56","",""
## Q:\Test\2018\05\31\SO_50617742.ps1
$BaseDir = "C:\Users\HOSDUM01\Desktop\Auto\Server_health_check\"
$ServerListFile = Join-Path $BaseDir "Server_list.txt"
$ReportHtm = Join-Path $BaseDir "Server_Test.htm"
$ReportCsv = Join-Path $BaseDir "Server_Test.csv"
function DriveFreePercent {
param ([string]$ComputerName,
[string]$DriveLetter)
Get-WmiObject -Class win32_Volume -ComputerName $ComputerName -Filter "DriveLetter = '$($DriveLetter):'" |
ForEach {"{0:N2}" -f (($_.FreeSpace / $_.Capacity)*100) }
}
$ServerList = Get-Content $ServerListFile -ErrorAction SilentlyContinue
$Result = #()
ForEach($computername in $ServerList) {
$Result += [PSCustomObject] #{
ServerName = "$computername"
CPULoad = ("{0}" -f (Get-WmiObject -ComputerName $computername win32_processor|Measure LoadPercentage -Average).Average)
MemLoad = (gwmi -Class win32_operatingsystem -ComputerName $computername |
ForEach{"{0:N2}" -f ((($_.TotalVisibleMemorySize - $_.FreePhysicalMemory)*100)/$_.TotalVisibleMemorySize)})
CDrive = (DriveFreePercent $ComputerName C)
EDrive = (DriveFreePercent $ComputerName E)
FDrive = (DriveFreePercent $ComputerName F)
}
}
$Outputreport = "<HTML><TITLE> Server Health Report </TITLE>
<BODY background-color:peachpuff>
<font color =""#99000"" face=""Microsoft Tai le"">
<H2> Server Health Report </H2></font>
<Table border=1 cellpadding=0 cellspacing=0>
<TR bgcolor=Cyan align=center>
<TD><B>EP_Server_Name</B></TD>
<TD><B>CPULOAD</B></TD>
<TD><B>MemLoad</B></TD>
<TD><B>C_Free</B></TD>
<TD><B>E_Free</B></TD>
<TD><B>F_Free</B></TD></TR>"
Foreach($Entry in $Result) {
if( ($Entry.CpuLoad) -ge "80" -or
($Entry.Memload) -ge "80" -or
($Entry.Cdrive) -le "20" -or
($Entry.Edrive) -le "20" -or
($Entry.Fdrive) -le "20") {
$Outputreport += "<TR bgcolor=red>"
} else {
$Outputreport += "<TR bgcolor=green>"
}
$Outputreport += "<TD>$($Entry.Servername)</TD>"
$Outputreport += "<TD align=center>$($Entry.CPULoad)%</TD>"
$Outputreport += "<TD align=center>$($Entry.MemLoad)%</TD>"
$Outputreport += "<TD align=center>$($Entry.Cdrive)%</TD>"
$Outputreport += "<TD align=center>$($Entry.Edrive)%</TD>"
$Outputreport += "<TD align=center>$($Entry.Fdrive)%</TD></TR>"
$Outputreport += "</Table></BODY></HTML>"
}
$Outputreport | Out-File $ReportHtm
$Result | Export-Csv $ReportCsv -NoTypeInformation
#Invoke-Expression $ReportHtm
#gc $ReportCsv
##Send email functionality from below line, use it if you want
$smtpServer = "Random"
$smtpFrom = "test#test.com"
$smtpTo = "test#test.com"
$messageSubject = "Servers Health report"
$message = New-Object System.Net.Mail.MailMessage $smtpfrom, $smtpto
$message.Subject = $messageSubject
$message.IsBodyHTML = $true
$message.Body = "<head><pre>$style</pre></head>"
$message.Body += $Outputreport
$smtp = New-Object Net.Mail.SmtpClient($smtpServer)
#$smtp.Send($message)
$result = #()
for ($i=1; $i -lt 5; $i++) {
$result += [PSCustomObject] #{
ServerName = "$i"
CPULoad = "$($AVGProc.Average)%"
MemLoad = "$($OS.MemoryUsage)%"
CDrive = "$($vol.'C PercentFree')%"
EDrive = "$($vol2.'E PercentFree')%"
FDrive = "$($vol3.'F PercentFree')%"
}
}
$result | ConvertTo-Csv
I have found this idea how to get drive size
I'm having problem incorporating it to my script as I don't know where to insert the code.
Also the idea is to have only one line per computer outputted even when multi hard drive system exists.
This is the code I'm working with it includes the "Get Drive Data" code
# Output file location to be changed as needed
$file="C:\scripts\reports\InentoryTest_$((Get-Date).ToString('MM-dd-yyyy')).csv"
$txt="c:\scripts\reports\InentoryTest-error_$((Get-Date).ToString('MM-dd-yyyy')).txt"
# Getting computers from Active Directory
$Computers = Get-ADComputer -Filter {Name -like 'M416*'} | select -expand name
Foreach($Computer in $Computers){
if(!(Test-Connection -ComputerName $Computer -BufferSize 16 -Count 1 -ea 0 -quiet))
{
write-host "Cannot reach $Computer is offline" -ForegroundColor red
}
else
{
$Output = #()
Try
{
# Get Drive Data
$disk = Get-WmiObject -ComputerName $Computer Win32_LogicalDisk | Where-Object { ( $_.DriveType ) -eq 3 -and ( ( $_.freespace / $_.size ) -lt .1 ) } | ForEach-Object -Process {
[pscustomobject] #{
Drive = $_.DeviceID
Size = '{0:N1}' -f ( $_.Size / 1GB )
Free = '{0:N1}' -f ( $_.freespace / 1GB )
PercentFree = '{0:N1}' -f ( $_.freespace / $_.size * 100 )
}
}
$domain = Get-WmiObject Win32_ComputerSystem -ComputerName $Computer -ErrorAction Stop
$os = Get-WmiObject Win32_OperatingSystem -ComputerName $Computer -ErrorAction Stop
$mac = Get-WmiObject -class Win32_NetworkAdapterConfiguration -Filter "IPEnabled='True'" -ComputerName $Computer -ErrorAction Stop
$bios = Get-WmiObject win32_bios -ComputerName $Computer -ErrorAction Stop
$cpu = Get-WmiObject –class Win32_processor -ComputerName $Computer -ErrorAction Stop
$AD = Get-ADComputer $Computer -properties Name,Lastlogondate,ipv4Address,enabled,description,DistinguishedName -ErrorAction Stop
$ram = "{0} GB" -f ((Get-WmiObject Win32_PhysicalMemory -ComputerName $Computer -ErrorAction Stop | Measure-Object Capacity -Sum).Sum / 1GB)
$pc = Get-WmiObject win32_computersystem -ComputerName $Computer -ErrorAction Stop | select #{Name = "Type";Expression = {if (($_.pcsystemtype -eq '2') )
{'Laptop'} Else {'Desktop Or Other'}}
},Manufacturer,#{Name = "Model";Expression = {if (($_.model -eq "$null") ) {'Virtual'} Else {$_.model}}},username
# Create Output
$data = New-Object PSObject -Property #{
SerialNumber = $bios.serialnumber -replace "-.*"
Computername = $AD.name
IPaddress = $AD.ipv4Address
MACaddress = $mac.MACAddress
Enabled = $AD.Enabled
Description = $AD.description
OU = $AD.DistinguishedName.split(',')[1].split('=')[1]
DC = $domain.domain
Type = $pc.type
Manufacturer = $pc.Manufacturer
Model = $pc.Model
RAM = $ram
Disk = $disk #Get Drive Data
ProcessorName = ($cpu.name | Out-String).Trim()
NumberOfCores = ($cpu.NumberOfCores | Out-String).Trim()
NumberOfLogicalProcessors = ($cpu.NumberOfLogicalProcessors | Out-String).Trim()
Addresswidth = ($cpu.Addresswidth | Out-String).Trim()
OperatingSystem = $os.caption
InstallDate = ([WMI] '').ConvertToDateTime($os.installDate)
LastLogonDate = $ld.lastlogondate
LoggedinUser = $pc.username
}
# Only do this kind of update if it hasn't failed yet
$Output += $data
$desc="$($mac.MACAddress) ( $($bios.serialnumber -replace "-.*") ) $($pc.Model) | $((Get-Date).ToString('MM-dd-yyyy'))"
#Set-ADComputer $Computer -Description $desc -verbose
$Output | select Computername,Enabled,Description,IPaddress,MACaddress,OU,DC,Type,SerialNumber,Manufacturer,Model,RAM,Disk,ProcessorName,NumberOfCores,NumberOfLogicalProcessors,Addresswidth,OperatingSystem,InstallDate,LoggedinUser,LastLogonDate | export-csv -Append $file -NoTypeInformation
}
Catch [Exception]
{
# Only do this kind of update if create output has failed
$ErrorMessage = $_.Exception.Message
Add-Content -value "$Computer, $ErrorMessage, skipping to next" $txt
#Set-ADComputer $Computer -Description $ErrorMessage
continue
}
}
}
You're building a complex hierarchical object so you'd be better off collecting all the objects then dumping the result as a JSON or XML file. But if you do want a flat string, then you'll have to explicitly format your disk data into a string before adding it to the object you're dumping to CSV. Something like:
$diskData = $disk | foreach {
"[Drive: $($_.DeviceID), Size: $([int]($_.Size/1GB)), FreeSpace: $([int]($_.freespace/1GB)), PercentFree: $([int]($_.freespace/$_.size *100))]"
}
$diskdata = $diskdata -join " "
So I have the below code which works quite well but for some reason it's only calculating my D: drive and not also my C: drive?
$computerName = Get-Wmiobject Win32_ComputerSystem
$computerOS = Get-Wmiobject Win32_OperatingSystem
$computerHDD = Get-Wmiobject Win32_LogicalDisk -Filter drivetype=3
ForEach($HDD in $computerHDD){
$txtObject = New-Object PSObject -property #{
'ComputerName' = $computerName.Name
'ComputerModel' = $computerName.Model
'SerialNumber' = $computerName.SerialNumber
'HDDSize' = "{0:N2}" -f ($HDD.Size/1GB)
'HDDFree' = "{0:P2}" -f ($HDD.FreeSpace/$HDD.Size)
'OS' = $computerOS.caption
'OS_type' = $computerOS.OSArchitecture
'User' = $computerName.UserName
}
}
$txtObject | Select-Object ComputerName, ComputerModel, SerialNumber, HDDSize, HDDFree, OS, Os_type, User | Out-File "$PSSCriptRoot\computer_info.txt" -Append
seems like you would need to make an array. Try this...
$computerName = Get-Wmiobject Win32_ComputerSystem
$computerOS = Get-Wmiobject Win32_OperatingSystem
$computerHDD = Get-Wmiobject Win32_LogicalDisk -Filter drivetype=3
$output = #()
ForEach($HDD in $computerHDD){
$txtObject = New-Object PSObject -property #{
'ComputerName' = $computerName.Name
'ComputerModel' = $computerName.Model
'SerialNumber' = $computerName.SerialNumber
'HDDSize' = "{0:N2}" -f ($HDD.Size/1GB)
'HDDFree' = "{0:P2}" -f ($HDD.FreeSpace/$HDD.Size)
'OS' = $computerOS.caption
'OS_type' = $computerOS.OSArchitecture
'User' = $computerName.UserName
}
$output += $txtObject
}
$output | Select-Object ComputerName, ComputerModel, SerialNumber, HDDSize, HDDFree, OS, Os_type, User | Out-File "$PSSCriptRoot\computer_info.txt" -Append
You're overwriting $txtObject on every iteration of the loop, so your output only contains the drive from the final iteration. Instead, you should be initializing $txtObject as an array and then appending each drive's information to that:
$computerHDD = Get-Wmiobject Win32_LogicalDisk -Filter drivetype=3
$txtObject = #()
ForEach($HDD in $computerHDD){
$txtObject += New-Object PSObject -property #{
# ...
}
}
$txtObject | Select-Object ... | Out-File "$PSSCriptRoot\computer_info.txt" -Append
Better yet, you can eliminate the loop and the variable and just use the pipeline:
$computerName = Get-WmiObject Win32_ComputerSystem
$computerOS = Get-WmiObject Win32_OperatingSystem
Get-WmiObject Win32_LogicalDisk -Filter drivetype=3 `
| ForEach-Object -Process {
New-Object PSObject -Property #{
'ComputerName' = $computerName.Name
'ComputerModel' = $computerName.Model
'SerialNumber' = $computerName.SerialNumber
'HDDSize' = "{0:N2}" -f ($_.Size/1GB)
'HDDFree' = "{0:P2}" -f ($_.FreeSpace/$_.Size)
'OS' = $computerOS.caption
'OS_type' = $computerOS.OSArchitecture
'User' = $computerName.UserName
};
} | Out-File "$PSSCriptRoot\computer_info.txt" -Append
Note that New-Object above is nearly identical to your original code except $_ has to be used instead of $HDD.