The problem arises when a computer has more than one hard drive. The excel spread sheet will not align up properly. When the next computer in the array fills in the spread sheet, it will not place its data under the 2 drives from the previous machine. If all the machines have one drive, all is great. The c drive should line up with the rest of the data
To understand what I mean, I have attached a screen shot of what I am talking about. Check out the Drive info. The C drive will continue to be more out of whack as more machines are added. The problem child is the $DiskItems = gwmi Win32_LogicalDisk -Comp $StrComputer | where {$_.DriveType -eq 3 } and the alignment within Excel when 2 drives are present.
# Functions Section
# ==============================================================================================
# Function Name 'WMI- Lookup' - Gathers info using WMI and places results in Excel Sheet
# ==============================================================================================
Function WMILookup {
foreach ($StrComputer in $colComputers){
$GenItems1 = gwmi Win32_ComputerSystem -Comp $StrComputer
$GenItems2 = gwmi Win32_OperatingSystem -Comp $StrComputer
$SysItems1 = gwmi Win32_BIOS -Comp $StrComputer
$SysItems2 = gwmi Win32_TimeZone -Comp $StrComputer
$SysItems3 = gwmi Win32_WmiSetting -Comp $StrComputer
$ProcItems1 = gwmi Win32_Processor -Comp $StrComputer
$MemItems1 = gwmi Win32_PhysicalMemory -Comp $StrComputer
$MemItems2 = gwmi Win32_PhysicalMemoryArray -Comp $StrComputer
$DiskItems = gwmi Win32_LogicalDisk -Comp $StrComputer | where {$_.DriveType -eq 3 }
$Software = gwmi Win32_Product -Comp $StrComputer | where { $_.Description -notlike 'Microsoft Office*' }
# $DiskPart = gwmi Win32_DiskPartition -ComputerName $StrComputer
$NetItems = gwmi Win32_NetworkAdapterConfiguration -Comp $StrComputer | where{$_.IPEnabled -eq "True" -and $_.DNSHostName -ne $NULL}
# Populate General Sheet(1) with information
foreach ($objItem in $GenItems1){
$Sheet1.Cells.Item($intRow, 1) = $StrComputer
$Sheet1.Cells.Item($intRow, 2) = $objItem.Manufacturer
$Sheet1.Cells.Item($intRow, 3) = $objItem.Model
$Sheet1.Cells.Item($intRow, 4) = $objItem.TotalPhysicalMemory / 1024 / 1024
$Sheet1.Cells.Item($intRow, 5) = $objItem.UserName
#$intRow = $intRow + 1
}
foreach ($objItem in $GenItems2){
$Sheet1.Cells.Item($intRow, 6) = $objItem.Caption
$Sheet1.Cells.Item($intRow, 13) = $objItem.Codeset
$Sheet1.Cells.Item($intRow, 14) = $objItem.CountryCode
$Sheet1.Cells.Item($intRow, 15) = $objItem.Locale
}
foreach ($objItem in $SysItems1){
$Sheet1.Cells.Item($intRow, 7) = $objItem.SerialNumber
}
foreach ($objItem in $SysItems2){
$Sheet1.Cells.Item($intRow, 8) = $objItem.Caption
}
foreach ($objItem in $DiskItems) {
$Sheet1.Cells.Item($intRowDisk, 9) = $objItem.DeviceID
$Sheet1.Cells.Item($intRowDisk, 10) = $objItem.Size/1024/1024/1024
$Sheet1.Cells.Item($intRowDisk, 11) = $objItem.FreeSpace/1024/1024/1024
$Sheet1.Cells.Item($intRowDisk, 12) = $objItem.Size/1024/1024/1024 - $objItem.FreeSpace/1024/1024/1024
$intRowDisk = $intRowDisk + 1
}
foreach ($objItem in $NetItems){
$Sheet1.Cells.Item($intRowNet, 16) = $objItem.IPAddress
$intRowNet = $intRowNet + 1
}
#Populate Software Sheet
foreach ($objItem in $Software){
$Sheet2.Cells.Item($intRowSoft, 1) = $StrComputer
$Sheet2.Cells.Item($intRowSoft, 2) = $objItem.Name
$Sheet2.Cells.Item($intRowSoft, 3) = $objItem.Vendor
$Sheet2.Cells.Item($intRowSoft, 4) = $objItem.Version
$intRowSoft = $intRowSoft + 1
}
$intRow = $intRow + 1
$intRowDisk = $intRowDisk + 1
$intRowNet = $intRowNet + 1
$intRowSoft = $intRowSoft + 1
}
}
# ==============================================================================================
# Function Name 'WMILookupCred'-Uses Alternative Credential-Gathers info using WMI.
# ==============================================================================================
Function WMILookupCred {
foreach ($StrComputer in $colComputers){
$GenItems1 = gwmi Win32_ComputerSystem -Comp $StrComputer
$GenItems2 = gwmi Win32_OperatingSystem -Comp $StrComputer
$SysItems1 = gwmi Win32_BIOS -Comp $StrComputer
$SysItems2 = gwmi Win32_TimeZone -Comp $StrComputer
$SysItems3 = gwmi Win32_WmiSetting -Comp $StrComputer
$ProcItems1 = gwmi Win32_Processor -Comp $StrComputer
$MemItems1 = gwmi Win32_PhysicalMemory -Comp $StrComputer
$MemItems2 = gwmi Win32_PhysicalMemoryArray -Comp $StrComputer
$DiskItems = gwmi Win32_LogicalDisk -Comp $StrComputer | where {$_.DriveType -eq 3 }
$Software = gwmi Win32_Product -Comp $StrComputer | where { $_.Description -notlike 'Microsoft Office*' }
# $DiskPart = gwmi Win32_DiskPartition -ComputerName $StrComputer
$NetItems = gwmi Win32_NetworkAdapterConfiguration -Comp $StrComputer | where{$_.IPEnabled -eq "True" -and $_.DNSHostName -ne $NULL}
# Populate General Sheet(1) with information
foreach ($objItem in $GenItems1){
$Sheet1.Cells.Item($intRow, 1) = $StrComputer
$Sheet1.Cells.Item($intRow, 2) = $objItem.Manufacturer
$Sheet1.Cells.Item($intRow, 3) = $objItem.Model
$Sheet1.Cells.Item($intRow, 4) = $objItem.TotalPhysicalMemory / 1024 / 1024
$Sheet1.Cells.Item($intRow, 5) = $objItem.UserName
}
foreach ($objItem in $GenItems2){
$Sheet1.Cells.Item($intRow, 6) = $objItem.Caption
$Sheet1.Cells.Item($intRow, 13) = $objItem.Codeset
$Sheet1.Cells.Item($intRow, 14) = $objItem.CountryCode
$Sheet1.Cells.Item($intRow, 15) = $objItem.Locale
}
foreach ($objItem in $SysItems1){
$Sheet1.Cells.Item($intRow, 7) = $objItem.SerialNumber
}
foreach ($objItem in $SysItems2){
$Sheet1.Cells.Item($intRow, 8) = $objItem.Caption
}
foreach ($objItem in $DiskItems) {
$Sheet1.Cells.Item($intRowDisk, 9) = $objItem.DeviceID
$Sheet1.Cells.Item($intRowDisk, 10) = $objItem.Size/1024/1024/1024
$Sheet1.Cells.Item($intRowDisk, 11) = $objItem.FreeSpace/1024/1024/1024
$Sheet1.Cells.Item($intRowDisk, 12) = $objItem.Size/1024/1024/1024 - $objItem.FreeSpace/1024/1024/1024
$intRowDisk = $intRowDisk + 1
}
foreach ($objItem in $NetItems){
$Sheet1.Cells.Item($intRowNet, 16) = $objItem.IPAddress
$intRowNet = $intRowNet + 1
}
#Populate Software Sheet
foreach ($objItem in $Software){
$Sheet2.Cells.Item($intRowSoft, 1) = $StrComputer
$Sheet2.Cells.Item($intRowSoft, 2) = $objItem.Name
$Sheet2.Cells.Item($intRowSoft, 3) = $objItem.Vendor
$Sheet2.Cells.Item($intRowSoft, 4) = $objItem.Version
$intRowSoft = $intRowSoft + 1
}
$intRow = $intRow + 1
$intRowDisk = $intRowDisk + 1
$intRowNet = $intRowNet + 1
$intRowSoft = $intRowSoft + 1
}
}
# =============================================================================================
# Function Name 'ListComputers' - Enumerates ALL computer objects in AD
# ==============================================================================================
Function ListComputers {
$strCategory = "computer"
$objDomain = New-Object System.DirectoryServices.DirectoryEntry
$objSearcher = New-Object System.DirectoryServices.DirectorySearcher
$objSearcher.SearchRoot = $objDomain
$objSearcher.Filter = ("(objectCategory=$strCategory)")
$colProplist = "name"
foreach ($i in $colPropList){$objSearcher.PropertiesToLoad.Add($i)}
$colResults = $objSearcher.FindAll()
foreach ($objResult in $colResults)
{$objComputer = $objResult.Properties; $objComputer.name}
}
# ==============================================================================================
# Function Name 'ListServers' - Enumerates ALL Servers objects in AD
# ==============================================================================================
Function ListServers {
$strCategory = "computer"
$strOS = "Windows*Server*"
$objDomain = New-Object System.DirectoryServices.DirectoryEntry
$objSearcher = New-Object System.DirectoryServices.DirectorySearcher
$objSearcher.SearchRoot = $objDomain
$objSearcher.Filter = ("(&(objectCategory=$strCategory)(OperatingSystem=$strOS))")
$colProplist = "name"
foreach ($i in $colPropList){$objSearcher.PropertiesToLoad.Add($i)}
$colResults = $objSearcher.FindAll()
foreach ($objResult in $colResults)
{$objComputer = $objResult.Properties; $objComputer.name}
}
# ========================================================================
# Function Name 'ListTextFile' - Enumerates Computer Names in a text file
# Create a text file and enter the names of each computer. One computer
# name per line. Supply the path to the text file when prompted.
# ========================================================================
Function ListTextFile {
$strText = Read-Host "Enter the path for the text file"
$colComputers = Get-Content $strText
}
# ========================================================================
# Function Name 'SingleEntry' - Enumerates Computer from user input
# ========================================================================
Function ManualEntry {
$colComputers = Read-Host "Enter Computer Name or IP"
}
# ==============================================================================================
# Script Body
# ==============================================================================================
# $erroractionpreference = "SilentlyContinue"
#Gather info from user.
Write-Host "********************************" -ForegroundColor Green
Write-Host "Computer Inventory Script" -ForegroundColor Green
Write-Host "by: " -ForegroundColor Green
Write-Host "Workplace" -ForegroundColor Green
Write-Host "PowerShell V3" -ForegroundColor Green
Write-Host "********************************" -ForegroundColor Green
Write-Host " "
Write-Host "Admin rights are required to enumerate information." -ForegroundColor Green
Write-Host "You need to use your TEN\-A.first.last account" -ForegroundColor Green
Write-Host "Would you like to use an alternative credential?" -ForegroundColor Green
$credResponse = Read-Host "[Y] Yes, [N] No"
If($CredResponse -eq "y"){$cred = Get-Credential DOMAIN\USER}
Write-Host " "
Write-Host "Which computer resources would you like in the report?" -ForegroundColor Green
$strResponse = Read-Host "[1] All Domain Computers, [2] All Domain Servers, [3] Computer names from a File, [4] Choose a Computer manually"
If($strResponse -eq "1"){$colComputers = ListComputers | Sort-Object}
elseif($strResponse -eq "2"){$colComputers = ListServers | Sort-Object}
elseif($strResponse -eq "3"){. ListTextFile}
elseif($strResponse -eq "4"){. ManualEntry}
else{Write-Host "You did not supply a correct response, `
Please run script again." -foregroundColor Red}
Write-Progress -Activity "Getting Inventory" -status "Running..." -id 1
#New Excel Application
$Excel = New-Object -Com Excel.Application
$Excel.visible = $True
# Create 2 worksheets
$Excel = $Excel.Workbooks.Add()
# Assign each worksheet to a variable and
# name the worksheet.
$Sheet1 = $Excel.Worksheets.Item(1)
$Sheet2 = $Excel.WorkSheets.Item(2)
$Sheet1.Name = "General"
$Sheet2.Name = "Software"
#Create Heading for General Sheet
$Sheet1.Cells.Item(1,1) = "Device_Name"
$Sheet1.Cells.Item(1,2) = "HW_Make"
$Sheet1.Cells.Item(1,3) = "HW_Model"
$Sheet1.Cells.Item(1,4) = "Memory_MB"
$Sheet1.Cells.Item(1,5) = "Login_Name"
$Sheet1.Cells.Item(1,6) = "Operating_System"
$Sheet1.Cells.Item(1,7) = "Serial_Number"
$Sheet1.Cells.Item(1,8) = "Time_Zone"
$Sheet1.Cells.Item(1,9) = "Drive_Letter"
$Sheet1.Cells.Item(1,10) = "Capacity_GB"
$Sheet1.Cells.Item(1,11) = "Free_Space_GB"
$Sheet1.Cells.Item(1,12) = "Used_Space_GB"
$Sheet1.Cells.Item(1,13) = "CodeSet"
$Sheet1.Cells.Item(1,14) = "Country_Code"
$Sheet1.Cells.Item(1,15) = "Locale"
$Sheet1.Cells.Item(1,16) = "IP Address"
#Create Heading for Software Sheet
$Sheet2.Cells.Item(1,1) = "Machine Name"
$Sheet2.Cells.Item(1,2) = "Software"
$Sheet2.Cells.Item(1,3) = "Vendor"
$Sheet2.Cells.Item(1,4) = "Version"
$colSheets = ($Sheet1, $Sheet2)
foreach ($colorItem in $colSheets){
$intRow = 2
$intRowDisk = 2
$intRowSoft = 2
$intRowNet = 2
$WorkBook = $colorItem.UsedRange
$WorkBook.Interior.ColorIndex = 20
$WorkBook.Font.ColorIndex = 11
$WorkBook.Font.Bold = $True
}
If($credResponse -eq "y"){WMILookupCred}
Else{WMILookup}
#Auto Fit all sheets in the Workbook
foreach ($colorItem in $colSheets){
$WorkBook = $colorItem.UsedRange
$WorkBook.EntireColumn.AutoFit()
clear
}
Write-Host "*******************************" -ForegroundColor Green
Write-Host "The Report has been completed." -ForeGroundColor Green
Write-Host "*******************************" -ForegroundColor Green
# ========================================================================
# END of Script
# ==================
You’re attempting to create a fixed-width table with a variable number of source data points. It’s not really about “alignment” as much as it is trying to keep your columns consistent with the same data in each row. Visually, it may be aligned, but look at it from the perspective of the data, because Excel is not a “visual layout” tool.
If your computers will have a variable number of certain devices (network interface, hard drive, etc.) you’d be better off putting those devices into their own worksheets, one row for each drive on each computer.
Essentially, you’re creating a database and need to normalize the data – what you’re attempting now is a denormalized structure, which will not meet your “alignment” requirement.