Create a Powershell server report using wmi - Noob needs help, please

I’m in need of creating a report that will help retrieve the following items in a CSV format:

Server/ ReportDate / TotalAllocation / UsedGB / SubtractedAmount / BilledAllocation / OperatingSystem / Version

I was able to modify a great script to get a few of the items on my report using the Class Win32_volume but not sure how to get the complete Total disk amount along with the UsedGB for all the Disks on a server.

$Server = Get-WmiObject -Class Win32_volume -computer $computer -filter "drivetype=3 AND DriveLetter != NULL"

I was trying to find a way to utilize the Win32_logicalDisk from the initial script I found but with my limited powershell skills, I was unable to gather/collect the needed information of each server.

$Disks = Get-WmiObject Win32_LogicalDisk -ComputerName $Computer -Filter "DriveType = 3" -ErrorAction Stop

 

Initial script - https://community.spiceworks.com/scripts/show/2147-get-diskinfo

 

Current attempt:

#Working on learning the steps of the script:

#This allows you to control the function of how the cmdlet itself works.  So it will require a Parameter and allows piping.

# Typical input - Get-Content c:\scripts\servers.txt | .\GetServerInfo.ps1 | Sort SystemName | Format-Table

#Most servers being queried will be SErver 2008 R2 or 2012 R2.

[CmdletBinding()]

Param(

[Parameter(Mandatory=$true,

ValueFromPipeline=$true)]

[String[]]$ComputerName,

[switch]$ShowAll

)

#This section creates HASH tables for each iteration it passes the ForEach loop

Begin {

$ServerResults = @()

$DiskResults = @()         

}

#Here is where each server in my servers.txt file will be processed.

Process {

    ForEach ($Computer in $ComputerName)

    {                         

                                $vp = "V"

                                $SAmount = '80'

                                $Drives = $computer.group        

                                $csvdetail = $drives | Select @{ Name = "Server"; Expression = { $computer.name } },

                                @{ Name = "ReportDate"; Expression = { Get-Date -Format g } },

                                @{ Name = "Drive"; Expression = { $_.DriveLetter } },

                                @{ Name = "SizeGB"; Expression = { "{0:N2}" -f ($_.Capacity/1GB) } },

                                @{ Name = "UsedGB"; Expression = { "{0:N2}" -f (($_.Capacity - $_.Freespace)/1GB) } },

                                @{ Name = "FreeGB"; Expression = { "{0:N2}" -f ($_.FreeSpace/1GB) } }

                                $Server = Get-WmiObject -Class Win32_volume -computer $computer -filter "drivetype=3 AND DriveLetter != NULL"

                                $SystemName                                  = $Server.SystemName

                                $ReportDate                      = Get-Date -format g

                                $MachineType                 = $vp

                                $subtractedAmount       = $SAmount

                                <#

                OperatingSystem = $operatingSystem.caption

                Version = $operatingSystem.Caption + " " + $operatingSystem.Version

                TotalAllocation = "{0:N2}" -f (($Drives | Measure-Object Capacity -Sum).Sum/1GB)

                FreeGB = "{0:N2}" -f (($Drives | Measure-Object FreeSpace -Sum).Sum/1GB)

                UsedGB = "{0:N2}" -f ((($Drives | Measure-Object Capacity -Sum).Sum/1GB) - (($Drives | Measure-Object FreeSpace -Sum).Sum/1GB))

                BilledAllocation = "{0:N2}" -f ((($Drives | Measure-Object Capacity -Sum).Sum/1GB) - $subtractedAmount)

                #>

                $ServerInfo = @{

                Server                                                   = $SystemName

                ReportDate                                        = $ReportDate

                MachineType                                    = $MachineType

                SubtractedAmount         = $subtractedAmount

                                                <#

                                                Additional hash variables will be added to above $serverInfo

                                                #>                                          

                                }

                                New-Object PSObject -Property $ServerInfo

                                $ServerInfo

                                }             

    }

End {     

                $ServerInfo

}

I know there are missing parts and I would be very grateful for any help on getting this report complete.

Cheers,

  • I thought I might have solved my issue but still unable to get the final output I need.

    At the ps prompt:

    .\GetServerInfo.ps1 -ComputerName ServerName

    And here is the contents of GetServerInfo.ps1:

    [CmdletBinding()]
    Param(
    [Parameter(Mandatory=$true,
    ValueFromPipeline=$true)]
    [String[]]$ComputerName,
    [switch]$ShowAll
    )

    $exportLocation = 'f:\temp\ServerReport.csv'

    foreach ($computer in $computers) {

    $Drives = $computer.group
    $csvdetail = $drives | Select @{ Name = "Server"; Expression = { $computer.name } },
    @{ Name = "ReportDate"; Expression = { Get-Date -Format g } },
    @{ Name = "Drive"; Expression = { $_.DriveLetter } },
    @{ Name = "SizeGB"; Expression = { "{0:N2}" -f ($_.Capacity/1GB) } },
    @{ Name = "UsedGB"; Expression = { "{0:N2}" -f (($_.Capacity - $_.Freespace)/1GB) } },
    @{ Name = "FreeGB"; Expression = { "{0:N2}" -f ($_.FreeSpace/1GB) } }



    $computerSystem = Get-WmiObject -Computer $computer.Name -Class 'Win32_ComputerSystem'
    $operatingSystem = Get-WmiObject -ComputerName $computer.Name -Class 'Win32_OperatingSystem'
    $Server = $computer.Name
    $ReportDate = Get-Date -format g
    $MachineType = "V"
    $SubtractedAmount = "80"
    $OperatingSystem = $operatingSystem.caption
    $Version = $operatingSystem.Caption + " " + $operatingSystem.Version
    $TotalAllocation = "{0:N2}" -f (($Drives | Measure-Object Capacity -Sum).Sum/1GB)
    $FreeGB = "{0:N2}" -f (($Drives | Measure-Object FreeSpace -Sum).Sum/1GB)
    $UsedGB = "{0:N2}" -f ((($Drives | Measure-Object Capacity -Sum).Sum/1GB) - (($Drives | Measure-Object FreeSpace -Sum).Sum/1GB))
    $BilledAllocation = "{0:N2}" -f ((($Drives | Measure-Object Capacity -Sum).Sum/1GB) - $subtractedAmount)


    $OutputObj = New-Object -Type PSObject
    $OutputObj | Add-Member -MemberType NoteProperty -Name ComputerName -Value $Computer.ToUpper()
    $OutputObj | Add-Member -MemberType NoteProperty -Name Report Date -Value $ReportDate
    $OutputObj | Add-Member -MemberType NoteProperty -Name TotalAllocation -Value $TotalAllocation
    $OutputObj | Add-Member -MemberType NoteProperty -Name UsedGB -Value $UsedGB
    $OutputObj | Add-Member -MemberType NoteProperty -Name SubtractedAmount -Value $SubtractedAmount
    $OutputObj | Add-Member -MemberType NoteProperty -Name BilledAllocation -Value $BilledAllocation
    $OutputObj | Add-Member -MemberType NoteProperty -Name Operating_System -Value $OperatingSystem
    $OutputObj | Add-Member -MemberType NoteProperty -Name Operating_System_BuildVersion -Value $Version
    $OutputObj | Export-Csv $exportLocation -Append -NoTypeInformation
    #$OutputObj | convertto-csv -NoTypeInformation | Out-File f:\Temp\Serverreport.csv
    }


    As you can notice, I commented out the last line, I first wanted to export to csv but tried using the other method. Neither provides me with the csv file.
    Any help would be appreciated.
  • You are not getting anything / results at all from this at all.

    This variable '$computers' is empty. You don't declare or use this anywhere.
    You only have and parameter array string called $ComputerName.

    Either change one or the other variable name.

    If you are just working with CompunetName as a simple string, then the rest of the script will simply not give you anything, because you are calling object items which do not exist.

    For example, simplifying this to just ask for the DiskInfo directly

    Function Get-ComputerInventoryReport
    {
    [CmdletBinding()]

    Param
    (
    [Parameter(Mandatory=$true,
    ValueFromPipeline=$true)]
    [String[]]$ComputerName
    )

    foreach ($computer in $ComputerName) {
    "`nProcessing actions on hostname $computer"

    'FileSystem drive on this computer are: '
    ($Drives = Get-PSDrive -PSProvider 'FileSystem')

    }
    }
    Get-ComputerInventoryReport -ComputerName $env:COMPUTERNAME,localhost

    # Results

    Processing actions on hostname PC01
    FileSystem drive on this computer are:

    Name Used (GB) Free (GB) Provider Root CurrentLocation
    ---- --------- --------- -------- ---- ---------------
    C 223.18 252.35 FileSystem C:\
    D 151.67 325.14 FileSystem D:\ Scripts
    E 1480.12 382.77 FileSystem E:\
    G FileSystem G:\
    H 2913.88 812.01 FileSystem H:\

    Processing actions on hostname localhost
    FileSystem drive on this computer are:
    C 223.18 252.35 FileSystem C:\
    D 151.67 325.14 FileSystem D:\ Scripts
    E 1480.12 382.77 FileSystem E:\
    G FileSystem G:\
    H 2913.88 812.01 FileSystem H:\


    Similarly, you'd need to change the other items to meet your needs.

    For example:

    This....

    $computerSystem = Get-WmiObject -Computer $computer.Name -Class 'Win32_ComputerSystem'
    $operatingSystem = Get-WmiObject -ComputerName $computer.Name -Class 'Win32_OperatingSystem'
    $Server = $computer.Name

    ...becomes this

    $computerSystem = Get-WmiObject -ComputerName $computer -Class 'Win32_ComputerSystem'
    $operatingSystem = Get-WmiObject -ComputerName $computer -Class 'Win32_OperatingSystem'
    $Server = $computer

    And so on.....
  • A couple of other points I failed to mention n my previous response.

    Often you really need to decide to build vs use when it comes to any tool, VBS, PoSH, whatever.

    Different version of PoSH have things pre-written for you in the cmdlets. This Computer Inventory thing you are trying is just one of those.

    If you are on a PoSH version that has the Get-ComputerInfo cmdlet, this should get you to what you need to go quickly.

    $PSVersionTable

    Name Value
    ---- -----
    PSVersion 5.1.16299.64
    PSEdition Desktop
    PSCompatibleVersions {1.0, 2.0, 3.0, 4.0...}
    BuildVersion 10.0.16299.64
    CLRVersion 4.0.30319.42000
    WSManStackVersion 3.0
    PSRemotingProtocolVersion 2.3
    SerializationVersion 1.1.0.1


    Using the built-in cmdlet
    Get-Command -Name Get-Computer*

    CommandType Name Version Source
    ----------- ---- ------- ------
    Cmdlet Get-ComputerInfo 3.1.0.0 Microsoft.PowerShell.Management
    Cmdlet Get-ComputerRestorePoint 3.1.0.0 Microsoft.PowerShell.Management


    Get-ComputerInfo

    Or even just use
    systeminfo
    but does require you to parse the output and it's a bit of a pain to do

    Also, I'd recommend you testing with this sample here:

    'gallery.technet.microsoft.com/scriptcenter/PowerShell-System-571521d1'
  • Thank you for the response...I did some clean up as suggested and then worked through the script again. I looked at several other similar scripts and just about have the report working as needed. However I have one major issue.
    At the command prompt: PS>get-content f:\temp\servers.txt | .\workingServerinfo.ps1

    The script creates the correct data but for only the last server in the list I provide.

    [CmdletBinding()]
    Param (
    [Parameter(Mandatory = $true,ValueFromPipeline = $true)]
    [String[]]$ComputerName
    )

    foreach ($computer in $ComputerName) {

    $drives = Get-WmiObject -Class Win32_volume -ComputerName $computer -filter "drivetype=3 AND DriveLetter != NULL"

    $csvdetail = $drives | Select @{ Name = "Server"; Expression = { $computer.name } },
    @{ Name = "ReportDate"; Expression = { Get-Date -Format g } },
    @{ Name = "Drive"; Expression = { $_.DriveLetter } },
    @{ Name = "SizeGB"; Expression = { "{0:N2}" -f ($_.Capacity/1GB) } },
    @{ Name = "UsedGB"; Expression = { "{0:N2}" -f (($_.Capacity - $_.Freespace)/1GB) } },
    @{ Name = "FreeGB"; Expression = { "{0:N2}" -f ($_.FreeSpace/1GB) } }



    $computerSystem = Get-WmiObject -ComputerName $computer -Class 'Win32_ComputerSystem'

    $operatingSystem = Get-WmiObject -ComputerName $computer -Class 'Win32_OperatingSystem'


    $Server = $computer
    $ReportDate = Get-Date -format g
    $MachineType = "V"
    $SubtractedAmount = "80"
    $OperatingSystem = $operatingSystem.caption
    $Version = $operatingSystem.Caption + " " + $operatingSystem.Version
    $TotalAllocation = "{0:N2}" -f (($Drives | Measure-Object Capacity -Sum).Sum/1GB)
    $FreeGB = "{0:N2}" -f (($Drives | Measure-Object FreeSpace -Sum).Sum/1GB)
    $UsedGB = "{0:N2}" -f ((($Drives | Measure-Object Capacity -Sum).Sum/1GB) - (($Drives | Measure-Object FreeSpace -Sum).Sum/1GB))
    $BilledAllocation = "{0:N2}" -f ((($Drives | Measure-Object Capacity -Sum).Sum/1GB) - $subtractedAmount)

    $OutputObj = New-Object -Type PSObject
    $OutputObj | Add-Member -MemberType NoteProperty -Name ComputerName -Value $Computer.ToUpper()
    $OutputObj | Add-Member -MemberType NoteProperty -Name ReportDate -Value $ReportDate
    $OutputObj | Add-Member -MemberType NoteProperty -Name TotalAllocation -Value $TotalAllocation
    $OutputObj | Add-Member -MemberType NoteProperty -Name UsedGB -Value $UsedGB
    $OutputObj | Add-Member -MemberType NoteProperty -Name SubtractedAmount -Value $SubtractedAmount
    $OutputObj | Add-Member -MemberType NoteProperty -Name BilledAllocation -Value $BilledAllocation
    $OutputObj | Add-Member -MemberType NoteProperty -Name Operating_System -Value $OperatingSystem
    $OutputObj | Add-Member -MemberType NoteProperty -Name Operating_System_BuildVersion -Value $Version
    #$OutputObj | Export-Csv $exportLocation -Append -NoTypeInformation
    #$OutputObj | convertto-csv -NoTypeInformation | Out-File f:\Temp\Serverreport.csv
    $OutputObj | Export-Csv -Path f:\Temp\Serverreport.csv -NoTypeInformation

    }

    Any assistance would be greatly appreciated.

    Getting close but still far from the finish line.
  • Well, that is because you are only outputting a single object and over writing the previous output.
    You have to collect all the objects then output to a file or output to a file and append to that file on each iteration.

    Also, as I indicated earlier, based on how you are doing from that text file, of inline input, this...

    $computer.name cannot be used as you do not have anything that does this.

    So, you need use only $computer, because that is the only string thing you are using.

    So, change this ...

    $csvdetail = $drives | Select @{ Name = "Server"; Expression = { $computer .name} },

    to this...
    $csvdetail = $drives | Select @{ Name = "Server"; Expression = { $computer } },

    Change this...

    $OutputObj | Export-Csv -Path f:\Temp\Serverreport.csv -NoTypeInformation

    to this...

    $OutputObj | Export-Csv -Path D:\Temp\Serverreport.csv -Append -NoTypeInformation


    So, for it all...

    Function Get-WorkingServerinfo
    {
    [CmdletBinding()]

    Param
    (
    [Parameter(Mandatory = $true,ValueFromPipeline = $true)]
    [String[]]$ComputerName
    )

    foreach ($computer in $ComputerName) {

    $drives = Get-WmiObject -Class Win32_volume -ComputerName $computer -filter "drivetype=3 AND DriveLetter != NULL"

    $csvdetail = $drives | Select @{ Name = "Server"; Expression = { $computer } },
    @{ Name = "ReportDate"; Expression = { Get-Date -Format g } },
    @{ Name = "Drive"; Expression = { $_.DriveLetter } },
    @{ Name = "SizeGB"; Expression = { "{0:N2}" -f ($_.Capacity/1GB) } },
    @{ Name = "UsedGB"; Expression = { "{0:N2}" -f (($_.Capacity - $_.Freespace)/1GB) } },
    @{ Name = "FreeGB"; Expression = { "{0:N2}" -f ($_.FreeSpace/1GB) } }



    $computerSystem = Get-WmiObject -ComputerName $computer -Class 'Win32_ComputerSystem'

    $operatingSystem = Get-WmiObject -ComputerName $computer -Class 'Win32_OperatingSystem'


    $Server = $computer
    $ReportDate = Get-Date -format g
    $MachineType = "V"
    $SubtractedAmount = "80"
    $OperatingSystem = $operatingSystem.caption
    $Version = $operatingSystem.Caption + " " + $operatingSystem.Version
    $TotalAllocation = "{0:N2}" -f (($Drives | Measure-Object Capacity -Sum).Sum/1GB)
    $FreeGB = "{0:N2}" -f (($Drives | Measure-Object FreeSpace -Sum).Sum/1GB)
    $UsedGB = "{0:N2}" -f ((($Drives | Measure-Object Capacity -Sum).Sum/1GB) - (($Drives | Measure-Object FreeSpace -Sum).Sum/1GB))
    $BilledAllocation = "{0:N2}" -f ((($Drives | Measure-Object Capacity -Sum).Sum/1GB) - $subtractedAmount)

    $OutputObj = New-Object -Type PSObject
    $OutputObj | Add-Member -MemberType NoteProperty -Name ComputerName -Value $Computer.ToUpper()
    $OutputObj | Add-Member -MemberType NoteProperty -Name ReportDate -Value $ReportDate
    $OutputObj | Add-Member -MemberType NoteProperty -Name TotalAllocation -Value $TotalAllocation
    $OutputObj | Add-Member -MemberType NoteProperty -Name UsedGB -Value $UsedGB
    $OutputObj | Add-Member -MemberType NoteProperty -Name SubtractedAmount -Value $SubtractedAmount
    $OutputObj | Add-Member -MemberType NoteProperty -Name BilledAllocation -Value $BilledAllocation
    $OutputObj | Add-Member -MemberType NoteProperty -Name Operating_System -Value $OperatingSystem
    $OutputObj | Add-Member -MemberType NoteProperty -Name Operating_System_BuildVersion -Value $Version
    #$OutputObj | Export-Csv $exportLocation -Append -NoTypeInformation
    #$OutputObj | convertto-csv -NoTypeInformation | Out-File f:\Temp\Serverreport.csv
    $OutputObj | Export-Csv -Path D:\Temp\Serverreport.csv -Append -NoTypeInformation

    }
    }


    Clear-Host
    $TargetHosts = '127.0.0.1','localhost',"$env:COMPUTERNAME"
    Get-workingServerinfo -ComputerName $TargetHosts

    # Results

    "ComputerName","ReportDate","TotalAllocation","UsedGB","SubtractedAmount","BilledAllocation","Operating_System","Operating_System_BuildVersion"
    "127.0.0.1","Mon 20 Nov 02017 19:04","6,541.13","4,772.64","80","6,461.13","Microsoft Windows 10 Pro"," "
    "LOCALHOST","Mon 20 Nov 02017 19:04","6,541.13","4,772.64","80","6,461.13","Microsoft Windows 10 Pro"," "
    "PC01","Mon 20 Nov 02017 19:04","6,541.13","4,772.64","80","6,461.13","Microsoft Windows 10 Pro"," "