Mark Damen
asked on
Powershell Script - Error "Unable to index into an object of type System.Management.Automation.PSObject"
This is my second PowerShell question in the last 20 mins...
So another Powershell that should be obvious, but isn't working for me. It's another one from the MS website.
I'm running it by using the simple example contained at the top of the script, but I get this error:
. .\Get-ComputerAssetInforma tion.ps1
Get-ComputerAssetInformati on -ComputerName localhost -ShowProgress
WARNING: localhost: Unable to index into an object of type System.Management.Automati on.PSObjec t.
So another Powershell that should be obvious, but isn't working for me. It's another one from the MS website.
function Get-ComputerAssetInformation
{
<#
.SYNOPSIS
Get inventory data for specified computer systems.
.DESCRIPTION
Gather inventory data for one or more systems using wmi. Data proccessing utilizes multiple runspaces
and supports custom timeout parameters in case of wmi problems. You can optionally include
drive, memory, and network information in the results. You can view verbose information on each
runspace thread in realtime with the -Verbose option.
.PARAMETER ComputerName
Specifies the target computer for data query.
.PARAMETER IncludeMemoryInfo
Include information about the memory arrays and the installed memory within them. (_Memory and _MemoryArray)
.PARAMETER IncludeDiskInfo
Include disk partition and mount point information. (_Disks)
.PARAMETER IncludeNetworkInfo
Include general network configuration for enabled interfaces. (_Network)
.PARAMETER ThrottleLimit
Specifies the maximum number of systems to inventory simultaneously
.PARAMETER Timeout
Specifies the maximum time in second command can run in background before terminating this thread.
.PARAMETER ShowProgress
Show progress bar information
.PARAMETER PromptForCredential
Prompt for remote system credential prior to processing request.
.PARAMETER Credential
Accept alternate credential (ignored if the localhost is processed)
.EXAMPLE
PS > Get-ComputerAssetInformation -ComputerName test1
ComputerName : TEST1
IsVirtual : False
Model : ProLiant DL380 G7
ChassisModel : Rack Mount Unit
OperatingSystem : Microsoft Windows Server 2008 R2 Enterprise
OSServicePack : 1
OSVersion : 6.1.7601
OSSKU : Enterprise Server Edition
OSArchitecture : x64
SystemArchitecture : x64
PhysicalMemoryTotal : 12.0 GB
PhysicalMemoryFree : 621.7 MB
VirtualMemoryTotal : 24.0 GB
VirtualMemoryFree : 5.7 GB
CPUCores : 24
CPUSockets : 2
SystemTime : 08/04/2013 20:33:47
LastBootTime : 07/16/2013 07:42:01
InstallDate : 07/02/2011 17:52:34
Uptime : 19 days 12 hours 51 minutes
Description
-----------
Query and display basic information ablout computer test1
.EXAMPLE
PS > $cred = Get-Credential
PS > $b = Get-ComputerAssetInformation -ComputerName Test1 -Credential $cred -IncludeMemoryInfo
PS > $b | Select MemorySlotsTotal,MemorySlotsUsed | fl
MemorySlotsTotal : 18
MemorySlotsUsed : 6
PS > $b._Memory | Select DeviceLocator,@{n='MemorySize'; e={$_.Capacity/1Gb}}
DeviceLocator MemorySize
------------- ----------
PROC 1 DIMM 3A 2
PROC 1 DIMM 6B 2
PROC 1 DIMM 9C 2
PROC 2 DIMM 3A 2
PROC 2 DIMM 6B 2
PROC 2 DIMM 9C 2
Description
-----------
Query information about computer test1 using alternate credentials, including detailed memory information. Return
physical memory slots available and in use. Then display the memory location and size.
.EXAMPLE
PS > $a = Get-ComputerAssetInformation -IncludeDiskInfo -IncludeMemoryInfo -IncludeNetworkInfo
PS > $a._MemorySlots | ft
Label Bank Detail FormFactor Capacity
----- ---- ------ ---------- --------
BANK 0 Bank 1 Synchronous SODIMM 4096
BANK 2 Bank 2 Synchronous SODIMM 4096
Description
-----------
Query local computer for all information, store the results in $a, then show the memory slot utilization in further
detail in tabular form.
.EXAMPLE
PS > (Get-ComputerAssetInformation -IncludeDiskInfo)._Disks
Drive : C:
DiskType : Partition
Description : Installable File System
VolumeName :
PercentageFree : 10.64
Disk : \\.\PHYSICALDRIVE0
SerialNumber : 0SGDENZA091227
FreeSpace : 6.3 GB
PrimaryPartition : True
DiskSize : 59.6 GB
Model : SAMSUNG SSD PM800 TH 64G
Partition : Disk #0, Partition #0
Description
-----------
Query information about computer, include disk information, and immediately display it.
.NOTES
Originally posted at: http://learn-powershell.net/2013/05/08/scripting-games-2013-event-2-favorite-and-not-so-favorite/
Author: Zachary Loeber
Props To: David Lee (www.linkedin.com/pub/david-lee/2/686/482/) - Helped to troubleshoot and resolve numerous aspects of this script
Site: http://www.the-little-things.net/
Requires: Powershell 2.0
Info: WMI prefered over CIM as there no speed advantage using cimsessions in multithreading against old systems. Starting
around line 263 you can modify the WMI_<Property>Props arrays to include extra wmi data for each element should you
require information I may have missed. You can also change the default display properties by modifying $defaultProperties.
Keep in mind that including extra elements like the drive space and network information will increase the processing time per
system. You may need to increase the timeout parameter accordingly.
Version History
1.1.6 - 8/19/2013
- Refactored the date/time calculations to be less region specific.
- Added PercentPhysicalMemoryUsed to general info section
1.1.5 - 8/16/2013
- Fixed minor powershell 2.0 compatibility issue with empty array detection in the mountpoint calculation area.
1.1.4 - 8/15/2013
- Fixed cpu architecture determination logic (again).
- Included _MemorySlots in the memory results option. This includes an array of objects describing the memory
array, which slots are utilized, and what type of ram is utilizing them.
- Added RAM lookup tables for memory model and details.
1.1.3 - 8/13/2013
- Fixed improper variable assignment for virtual platform detection
- Changed network connection results to simply include all adapters, connected or not and include a new derived property called
'ConnectionStatus'. This fixes a backwards compatibility issue with pre-2008 servers and network detection.
- Added nic promiscuous mode detection for adapters.
(http://praetorianprefect.com/archives/2009/09/whos-being-promiscuous-in-your-active-directory/)
1.1.2 - 8/12/2013
- Fixed a backward compatibility bug with SystemArchitecture and OSArchitecture properties
- Added the actual network adapter display name to the _Network results.
- Added another example in the comment based help
1.1.1 - 8/7/2013
- Added wmi BIOS information to results (as _BIOS)
- Added IsVirtual and VirtualType to default result properties
1.1.0 - 8/3/2013
- Added several parameters
- Removed parameter sets in favor of arrays of custom object as note properties
- Removed ICMP response requirements
- Included more verbose runspace logging
1.0.2 - 8/2/2013
- Split out system and OS architecture (changing how each it determined)
1.0.1 - 8/1/2013
- Updated to include several more bits of information and customization variables
1.0.0 - ???
- Discovered original script on the internet and totally was blown away at how awesome it is.
#>
[CmdletBinding()]
Param
(
[Parameter(ValueFromPipeline=$true,
ValueFromPipelineByPropertyName=$true,
Position=0)]
[ValidateNotNullOrEmpty()]
[Alias('DNSHostName','PSComputerName')]
[string[]]
$ComputerName=$env:computername,
[Parameter()]
[switch]
$IncludeMemoryInfo,
[Parameter()]
[switch]
$IncludeDiskInfo,
[Parameter()]
[switch]
$IncludeNetworkInfo,
[Parameter()]
[ValidateRange(1,65535)]
[int32]
$ThrottleLimit = 32,
[Parameter()]
[ValidateRange(1,65535)]
[int32]
$Timeout = 120,
[Parameter()]
[switch]
$ShowProgress,
[Parameter()]
[switch]
$PromptForCredential,
[Parameter()]
[System.Management.Automation.Credential()]
$Credential = [System.Management.Automation.PSCredential]::Empty
)
Begin
{
# Gather possible local host names and IPs to prevent credential utilization in some cases
Write-Verbose -Message 'Creating local hostname list'
$IPAddresses = [net.dns]::GetHostAddresses($env:COMPUTERNAME) | Select-Object -ExpandProperty IpAddressToString
$HostNames = $IPAddresses | ForEach-Object {
try {
[net.dns]::GetHostByAddress($_)
} catch {
# We do not care about errors here...
}
} | Select-Object -ExpandProperty HostName -Unique
$LocalHost = @('', '.', 'localhost', $env:COMPUTERNAME, '::1', '127.0.0.1') + $IPAddresses + $HostNames
Write-Verbose -Message 'Creating initial variables'
$runspacetimers = [HashTable]::Synchronized(@{})
$runspaces = New-Object -TypeName System.Collections.ArrayList
$bgRunspaceCounter = 0
if ($PromptForCredential)
{
$Credential = Get-Credential
}
Write-Verbose -Message 'Creating Initial Session State'
$iss = [System.Management.Automation.Runspaces.InitialSessionState]::CreateDefault()
foreach ($ExternalVariable in ('runspacetimers', 'Credential', 'LocalHost'))
{
Write-Verbose -Message "Adding variable $ExternalVariable to initial session state"
$iss.Variables.Add((New-Object -TypeName System.Management.Automation.Runspaces.SessionStateVariableEntry -ArgumentList $ExternalVariable, (Get-Variable -Name $ExternalVariable -ValueOnly), ''))
}
Write-Verbose -Message 'Creating runspace pool'
$rp = [System.Management.Automation.Runspaces.RunspaceFactory]::CreateRunspacePool(1, $ThrottleLimit, $iss, $Host)
$rp.Open()
# This is the actual code called for each computer
Write-Verbose -Message 'Defining background runspaces scriptblock'
$ScriptBlock = {
[CmdletBinding()]
Param
(
[Parameter(Position=0)]
[string]
$ComputerName,
[Parameter(Position=1)]
[int]
$bgRunspaceID,
[Parameter()]
[switch]
$IncludeMemoryInfo,
[Parameter()]
[switch]
$IncludeDiskInfo,
[Parameter()]
[switch]
$IncludeNetworkInfo
)
$runspacetimers.$bgRunspaceID = Get-Date
try
{
Write-Verbose -Message ('Runspace {0}: Start' -f $ComputerName)
$WMIHast = @{
ComputerName = $ComputerName
ErrorAction = 'Stop'
}
if (($LocalHost -notcontains $ComputerName) -and ($Credential -ne $null))
{
$WMIHast.Credential = $Credential
}
#Due to some bug setting scriptblock directly as value can cause 'NullReferenceException' in v3 host
$ReadableOutput = @{
Name = 'ToString'
MemberType = 'ScriptMethod'
PassThru = $true
Force = $true
Value = [ScriptBlock]::Create(@"
"{0:N1} {1}" -f @(
switch -Regex ([math]::Log(`$this,1024)) {
^0 {
(`$this / 1), ' B'
}
^1 {
(`$this / 1KB), 'KB'
}
^2 {
(`$this / 1MB), 'MB'
}
^3 {
(`$this / 1GB), 'GB'
}
^4 {
(`$this / 1TB), 'TB'
}
default {
(`$this / 1PB), 'PB'
}
}
)
"@
)
}
#region GeneralInfo
Write-Verbose -Message ('Runspace {0}: General asset information' -f $ComputerName)
## Lookup arrays
$SKUs = @("Undefined","Ultimate Edition","Home Basic Edition","Home Basic Premium Edition","Enterprise Edition",`
"Home Basic N Edition","Business Edition","Standard Server Edition","DatacenterServer Edition","Small Business Server Edition",`
"Enterprise Server Edition","Starter Edition","Datacenter Server Core Edition","Standard Server Core Edition",`
"Enterprise ServerCoreEdition","Enterprise Server Edition for Itanium-Based Systems","Business N Edition","Web Server Edition",`
"Cluster Server Edition","Home Server Edition","Storage Express Server Edition","Storage Standard Server Edition",`
"Storage Workgroup Server Edition","Storage Enterprise Server Edition","Server For Small Business Edition","Small Business Server Premium Edition")
$ChassisModels = @("PlaceHolder","Maybe Virtual Machine","Unknown","Desktop","Thin Desktop","Pizza Box","Mini Tower","Full Tower","Portable",`
"Laptop","Notebook","Hand Held","Docking Station","All in One","Sub Notebook","Space-Saving","Lunch Box","Main System Chassis",`
"Lunch Box","SubChassis","Bus Expansion Chassis","Peripheral Chassis","Storage Chassis" ,"Rack Mount Unit","Sealed-Case PC")
$NetConnectionStatus = @('Disconnected','Connecting','Connected','Disconnecting','Hardware not present','Hardware disabled','Hardware malfunction',`
'Media disconnected','Authenticating','Authentication succeeded','Authentication failed','Invalid address','Credentials required')
$MemoryModels = @("Unknown","Other","SIP","DIP","ZIP","SOJ","Proprietary","SIMM","DIMM","TSOP","PGA","RIMM",`
"SODIMM","SRIMM","SMD","SSMP","QFP","TQFP","SOIC","LCC","PLCC","BGA","FPBGA","LGA")
$MemoryDetail = @{
'1' = 'Reserved'
'2' = 'Other'
'4' = 'Unknown'
'8' = 'Fast-paged'
'16' = 'Static column'
'32' = 'Pseudo-static'
'64' = 'RAMBUS'
'128' = 'Synchronous'
'256' = 'CMOS'
'512' = 'EDO'
'1024' = 'Window DRAM'
'2048' = 'Cache DRAM'
'4096' = 'Nonvolatile'
}
# Modify this variable to change your default set of display properties
$defaultProperties = @('ComputerName','IsVirtual','Model','ChassisModel','OperatingSystem','OSServicePack','OSVersion','OSSKU', `
'OSArchitecture','SystemArchitecture','PhysicalMemoryTotal','PhysicalMemoryFree','VirtualMemoryTotal', `
'VirtualMemoryFree','CPUCores','CPUSockets','SystemTime','LastBootTime','InstallDate','Uptime')
# WMI Properties
$WMI_OSProps = @('BuildNumber','Version','SerialNumber','ServicePackMajorVersion','CSDVersion','SystemDrive',`
'SystemDirectory','WindowsDirectory','Caption','TotalVisibleMemorySize','FreePhysicalMemory',`
'TotalVirtualMemorySize','FreeVirtualMemory','OSArchitecture','Organization','LocalDateTime',`
'RegisteredUser','OperatingSystemSKU','OSType','LastBootUpTime','InstallDate')
$WMI_ProcProps = @('Name','Description','MaxClockSpeed','CurrentClockSpeed','AddressWidth','NumberOfCores','NumberOfLogicalProcessors', `
'DataWidth')
$WMI_CompProps = @('DNSHostName','Domain','Manufacturer','Model','NumberOfLogicalProcessors','NumberOfProcessors','PrimaryOwnerContact', `
'PrimaryOwnerName','TotalPhysicalMemory')
$WMI_ChassisProps = @('ChassisTypes','Manufacturer','SerialNumber','Tag','SKU')
$WMI_BIOSProps = @('Version','SerialNumber')
# WMI data
$wmi_compsystem = Get-WmiObject @WMIHast -Class Win32_ComputerSystem | select $WMI_CompProps
$wmi_os = Get-WmiObject @WMIHast -Class Win32_OperatingSystem | select $WMI_OSProps
$wmi_proc = Get-WmiObject @WMIHast -Class Win32_Processor | select $WMI_ProcProps
$wmi_chassis = Get-WmiObject @WMIHast -Class Win32_SystemEnclosure | select $WMI_ChassisProps
$wmi_bios = Get-WmiObject @WMIHast -Class Win32_BIOS | select $WMI_BIOSProps
## Calculated properties
# CPU count
if (@($wmi_proc)[0].NumberOfCores) #Modern OS
{
$Sockets = @($wmi_proc).Count
$Cores = ($wmi_proc | Measure-Object -Property NumberOfLogicalProcessors -Sum).Sum
}
else #Legacy OS
{
$Sockets = @($wmi_proc | Select-Object -Property SocketDesignation -Unique).Count
$Cores = @($wmi_proc).Count
}
# OperatingSystemSKU is not availble in 2003 and XP
if ($wmi_os.OperatingSystemSKU -ne $null)
{
$OS_SKU = $SKUs[$wmi_os.OperatingSystemSKU]
}
else
{
$OS_SKU = 'Not Available'
}
$temptime = ([wmi]'').ConvertToDateTime($wmi_os.LocalDateTime)
$System_Time = "$($temptime.ToShortDateString()) $($temptime.ToShortTimeString())"
$temptime = ([wmi]'').ConvertToDateTime($wmi_os.LastBootUptime)
$OS_LastBoot = "$($temptime.ToShortDateString()) $($temptime.ToShortTimeString())"
$temptime = ([wmi]'').ConvertToDateTime($wmi_os.LastBootUptime)
$OS_InstallDate = "$($temptime.ToShortDateString()) $($temptime.ToShortTimeString())"
$Uptime = New-TimeSpan -Start $OS_LastBoot -End $System_Time
$IsVirtual = $false
$VirtualType = ''
if ($wmi_bios.Version -match "VIRTUAL")
{
$IsVirtual = $true
$VirtualType = "Virtual - Hyper-V"
}
elseif ($wmi_bios.Version -match "A M I")
{
$IsVirtual = $true
$VirtualType = "Virtual - Virtual PC"
}
elseif ($wmi_bios.Version -like "*Xen*")
{
$IsVirtual = $true
$VirtualType = "Virtual - Xen"
}
elseif ($wmi_bios.SerialNumber -like "*VMware*")
{
$IsVirtual = $true
$VirtualType = "Virtual - VMWare"
}
elseif ($wmi_compsystem.manufacturer -like "*Microsoft*")
{
$IsVirtual = $true
$VirtualType = "Virtual - Hyper-V"
}
elseif ($wmi_compsystem.manufacturer -like "*VMWare*")
{
$IsVirtual = $true
$VirtualType = "Virtual - VMWare"
}
elseif ($wmi_compsystem.model -like "*Virtual*")
{
$IsVirtual = $true
$VirtualType = "Unknown Virtual Machine"
}
$ResultProperty = @{
### Defaults
'PSComputerName' = $ComputerName
'IsVirtual' = $IsVirtual
'VirtualType' = $VirtualType
'Model' = $wmi_compsystem.Model
'ChassisModel' = $ChassisModels[$wmi_chassis.ChassisTypes[0]]
'ComputerName' = $wmi_compsystem.DNSHostName
'OperatingSystem' = $wmi_os.Caption
'OSServicePack' = $wmi_os.ServicePackMajorVersion
'OSVersion' = $wmi_os.Version
'OSSKU' = $OS_SKU
'OSArchitecture' = "x" + $wmi_proc[0].AddressWidth
'SystemArchitecture' = "x" + $wmi_proc[0].DataWidth
'PhysicalMemoryTotal' = ($wmi_os.TotalVisibleMemorySize * 1024) | Add-Member @ReadableOutput
'PhysicalMemoryFree' = ($wmi_os.FreePhysicalMemory * 1024) | Add-Member @ReadableOutput
'PercentPhysicalMemoryUsed' = [math]::round(((($wmi_os.TotalVisibleMemorySize - $wmi_os.FreePhysicalMemory)/$wmi_os.TotalVisibleMemorySize) * 100),2)
'VirtualMemoryTotal' = ($wmi_os.TotalVirtualMemorySize * 1024) | Add-Member @ReadableOutput
'VirtualMemoryFree' = ($wmi_os.FreeVirtualMemory * 1024) | Add-Member @ReadableOutput
'CPUCores' = $Cores
'CPUSockets' = $Sockets
'LastBootTime' = $OS_LastBoot
'InstallDate' = $OS_InstallDate
'SystemTime' = $System_Time
'Uptime' = "$($Uptime.days) days $($Uptime.hours) hours $($Uptime.minutes) minutes"
'_BIOS' = $wmi_bios
'_OS' = $wmi_os
'_System' = $wmi_compsystem
'_Processor' = $wmi_proc
'_Chassis' = $wmi_chassis
}
#endregion GeneralInfo
#region Memory
if ($IncludeMemoryInfo)
{
Write-Verbose -Message ('Runspace {0}: Memory information' -f $ComputerName)
$WMI_MemProps = @('BankLabel','DeviceLocator','Capacity','PartNumber','Speed','Tag','FormFactor','TypeDetail')
$WMI_MemArrayProps = @('Tag','MemoryDevices','MaxCapacity')
$wmi_memory = Get-WmiObject @WMIHast -Class Win32_PhysicalMemory | select $WMI_MemProps
$wmi_memoryarray = Get-WmiObject @WMIHast -Class Win32_PhysicalMemoryArray | select $WMI_MemArrayProps
# Memory Calcs
$Memory_Slotstotal = 0
$Memory_SlotsUsed = (@($wmi_memory)).Count
@($wmi_memoryarray) | % {$Memory_Slotstotal = $Memory_Slotstotal + $_.MemoryDevices}
# Add to the existing property set
$ResultProperty.MemorySlotsTotal = $Memory_Slotstotal
$ResultProperty.MemorySlotsUsed = $Memory_SlotsUsed
$ResultProperty._MemoryArray = $wmi_memoryarray
$ResultProperty._Memory = $wmi_memory
# Add a few of these properties to our default property set
$defaultProperties += 'MemorySlotsTotal'
$defaultProperties += 'MemorySlotsUsed'
# Add a more detailed memory slot utilization object array (cause I'm nice)
$membankcounter = 1
$MemorySlotOutput = @()
foreach ($obj1 in $wmi_memoryarray)
{
$slots = $obj1.MemoryDevices + 1
foreach ($obj2 in $wmi_memory)
{
if($obj2.BankLabel -eq "")
{
$MemLabel = $obj2.DeviceLocator
}
else
{
$MemLabel = $obj2.BankLabel
}
$slotprops = @{
'Bank' = "Bank " + $membankcounter
'Label' = $MemLabel
'Capacity' = $obj2.Capacity/1024/1024
'FormFactor' = $MemoryModels[$obj2.FormFactor]
'Detail' = $MemoryDetail[[string]$obj2.TypeDetail]
}
$MemorySlotOutput += New-Object PSObject -Property $slotprops
$membankcounter = $membankcounter + 1
}
while($membankcounter -lt $slots)
{
$slotprops = @{
'Bank' = "Bank " + $membankcounter
'Label' = "EMPTY"
'Capacity' = "0"
'FormFactor' = "EMPTY"
'Detail' = "EMPTY"
}
$MemorySlotOutput += New-Object PSObject -Property $slotprops
$membankcounter = $membankcounter + 1
}
}
$ResultProperty._MemorySlots = $MemorySlotOutput
}
#endregion Memory
#region Network
if ($IncludeNetworkInfo)
{
Write-Verbose -Message ('Runspace {0}: Network information' -f $ComputerName)
$wmi_netadapters = Get-WmiObject @WMIHast -Class Win32_NetworkAdapter
$alladapters = @()
ForEach ($adapter in $wmi_netadapters)
{
$wmi_netconfig = Get-WmiObject @WMIHast -Class Win32_NetworkAdapterConfiguration `
-Filter "Index = '$($Adapter.Index)'"
$wmi_promisc = Get-WmiObject @WMIHast -Class MSNdis_CurrentPacketFilter `
-Namespace 'root\WMI' `
-Filter "InstanceName = '$($Adapter.Name)'"
$promisc = $False
if ($wmi_promisc.NdisCurrentPacketFilter -band 0x00000020)
{
$promisc = $True
}
$NetConStat = ''
if ($adapter.NetConnectionStatus -ne $null)
{
$NetConStat = $NetConnectionStatus[$adapter.NetConnectionStatus]
}
$alladapters += New-Object PSObject -Property @{
NetworkName = $adapter.NetConnectionID
AdapterName = $adapter.Name
ConnectionStatus = $NetConStat
Index = $wmi_netconfig.Index
IpAddress = $wmi_netconfig.IpAddress
IpSubnet = $wmi_netconfig.IpSubnet
MACAddress = $wmi_netconfig.MACAddress
DefaultIPGateway = $wmi_netconfig.DefaultIPGateway
Description = $wmi_netconfig.Description
InterfaceIndex = $wmi_netconfig.InterfaceIndex
DHCPEnabled = $wmi_netconfig.DHCPEnabled
DHCPServer = $wmi_netconfig.DHCPServer
DNSDomain = $wmi_netconfig.DNSDomain
DNSDomainSuffixSearchOrder = $wmi_netconfig.DNSDomainSuffixSearchOrder
DomainDNSRegistrationEnabled = $wmi_netconfig.DomainDNSRegistrationEnabled
WinsPrimaryServer = $wmi_netconfig.WinsPrimaryServer
WinsSecondaryServer = $wmi_netconfig.WinsSecondaryServer
PromiscuousMode = $promisc
}
}
$ResultProperty._Network = $alladapters
}
#endregion Network
#region Disk
if ($IncludeDiskInfo)
{
Write-Verbose -Message ('Runspace {0}: Disk information' -f $ComputerName)
$WMI_DiskPartProps = @('DiskIndex','Index','Name','DriveLetter','Caption','Capacity','FreeSpace','SerialNumber')
$WMI_DiskVolProps = @('Name','DriveLetter','Caption','Capacity','FreeSpace','SerialNumber')
$WMI_DiskMountProps = @('Name','Label','Caption','Capacity','FreeSpace','Compressed','PageFilePresent','SerialNumber')
# WMI data
$wmi_diskdrives = Get-WmiObject @WMIHast -Class Win32_DiskDrive | select $WMI_DiskDriveProps
$wmi_mountpoints = Get-WmiObject @WMIHast -Class Win32_Volume -Filter "DriveType=3 AND DriveLetter IS NULL" | select $WMI_DiskMountProps
$AllDisks = @()
foreach ($diskdrive in $wmi_diskdrives)
{
$partitionquery = "ASSOCIATORS OF {Win32_DiskDrive.DeviceID=`"$($diskdrive.DeviceID.replace('\','\\'))`"} WHERE AssocClass = Win32_DiskDriveToDiskPartition"
$partitions = @(Get-WmiObject @WMIHast -Query $partitionquery)
foreach ($partition in $partitions)
{
$logicaldiskquery = "ASSOCIATORS OF {Win32_DiskPartition.DeviceID=`"$($partition.DeviceID)`"} WHERE AssocClass = Win32_LogicalDiskToPartition"
$logicaldisks = @(Get-WmiObject @WMIHast -Query $logicaldiskquery)
foreach ($logicaldisk in $logicaldisks)
{
$diskprops = @{
Disk = $diskdrive.Name
Model = $diskdrive.Model
Partition = $partition.Name
Description = $partition.Description
PrimaryPartition = $partition.PrimaryPartition
VolumeName = $logicaldisk.VolumeName
Drive = $logicaldisk.Name
DiskSize = $logicaldisk.Size | Add-Member @ReadableOutput
FreeSpace = $logicaldisk.FreeSpace | Add-Member @ReadableOutput
PercentageFree = [math]::round((($logicaldisk.FreeSpace/$logicaldisk.Size)*100), 2)
DiskType = 'Partition'
SerialNumber = $diskdrive.SerialNumber
}
$AllDisks += New-Object psobject -Property $diskprops
}
}
}
# Mountpoints are wierd so we do them seperate.
if ($wmi_mountpoints)
{
foreach ($mountpoint in $wmi_mountpoints)
{
$diskprops = @{
Disk = $mountpoint.Name
Model = ''
Partition = ''
Description = $mountpoint.Caption
PrimaryPartition = ''
VolumeName = ''
VolumeSerialNumber = ''
Drive = [Regex]::Match($mountpoint.Caption, "^.:\\").Value
DiskSize = $mountpoint.Capacity | Add-Member @ReadableOutput
FreeSpace = $mountpoint.FreeSpace | Add-Member @ReadableOutput
PercentageFree = [math]::round((($mountpoint.FreeSpace/$mountpoint.Capacity)*100), 2)
DiskType = 'MountPoint'
SerialNumber = $mountpoint.SerialNumber
}
$AllDisks += New-Object psobject -Property $diskprops
}
}
$ResultProperty._Disks = $AllDisks
}
#endregion Disk
# Final output
$ResultObject = New-Object -TypeName PSObject -Property $ResultProperty
# Setup the default properties for output
$ResultObject.PSObject.TypeNames.Insert(0,'My.Asset.Info')
$defaultDisplayPropertySet = New-Object System.Management.Automation.PSPropertySet(‘DefaultDisplayPropertySet’,[string[]]$defaultProperties)
$PSStandardMembers = [System.Management.Automation.PSMemberInfo[]]@($defaultDisplayPropertySet)
$ResultObject | Add-Member MemberSet PSStandardMembers $PSStandardMembers
Write-Output -InputObject $ResultObject
}
catch
{
Write-Warning -Message ('{0}: {1}' -f $ComputerName, $_.Exception.Message)
}
Write-Verbose -Message ('Runspace {0}: End' -f $ComputerName)
}
function Get-Result
{
[CmdletBinding()]
Param
(
[switch]$Wait
)
do
{
$More = $false
foreach ($runspace in $runspaces)
{
$StartTime = $runspacetimers.($runspace.ID)
if ($runspace.Handle.isCompleted)
{
Write-Verbose -Message ('Thread done for {0}' -f $runspace.IObject)
$runspace.PowerShell.EndInvoke($runspace.Handle)
$runspace.PowerShell.Dispose()
$runspace.PowerShell = $null
$runspace.Handle = $null
}
elseif ($runspace.Handle -ne $null)
{
$More = $true
}
if ($Timeout -and $StartTime)
{
if ((New-TimeSpan -Start $StartTime).TotalSeconds -ge $Timeout -and $runspace.PowerShell)
{
Write-Warning -Message ('Timeout {0}' -f $runspace.IObject)
$runspace.PowerShell.Dispose()
$runspace.PowerShell = $null
$runspace.Handle = $null
}
}
}
if ($More -and $PSBoundParameters['Wait'])
{
Start-Sleep -Milliseconds 100
}
foreach ($threat in $runspaces.Clone())
{
if ( -not $threat.handle)
{
Write-Verbose -Message ('Removing {0} from runspaces' -f $threat.IObject)
$runspaces.Remove($threat)
}
}
if ($ShowProgress)
{
$ProgressSplatting = @{
Activity = 'Getting asset info'
Status = '{0} of {1} total threads done' -f ($bgRunspaceCounter - $runspaces.Count), $bgRunspaceCounter
PercentComplete = ($bgRunspaceCounter - $runspaces.Count) / $bgRunspaceCounter * 100
}
Write-Progress @ProgressSplatting
}
}
while ($More -and $PSBoundParameters['Wait'])
}
}
Process
{
foreach ($Computer in $ComputerName)
{
$bgRunspaceCounter++
$psCMD = [System.Management.Automation.PowerShell]::Create().AddScript($ScriptBlock)
$null = $psCMD.AddParameter('bgRunspaceID',$bgRunspaceCounter)
$null = $psCMD.AddParameter('ComputerName',$Computer)
$null = $psCMD.AddParameter('IncludeMemoryInfo',$IncludeMemoryInfo)
$null = $psCMD.AddParameter('IncludeDiskInfo',$IncludeDiskInfo)
$null = $psCMD.AddParameter('IncludeNetworkInfo',$IncludeNetworkInfo)
$null = $psCMD.AddParameter('Verbose',$VerbosePreference) # Passthrough the hidden verbose option so write-verbose works within the runspaces
$psCMD.RunspacePool = $rp
Write-Verbose -Message ('Starting {0}' -f $Computer)
[void]$runspaces.Add(@{
Handle = $psCMD.BeginInvoke()
PowerShell = $psCMD
IObject = $Computer
ID = $bgRunspaceCounter
})
Get-Result
}
}
End
{
Get-Result -Wait
if ($ShowProgress)
{
Write-Progress -Activity 'Getting asset info' -Status 'Done' -Completed
}
Write-Verbose -Message "Closing runspace pool"
$rp.Close()
$rp.Dispose()
}
}
I'm running it by using the simple example contained at the top of the script, but I get this error:
. .\Get-ComputerAssetInforma
Get-ComputerAssetInformati
WARNING: localhost: Unable to index into an object of type System.Management.Automati
SOLUTION
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
SOLUTION
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
ASKER
ASKER
SOLUTION
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
ASKER
Windows 7 32bit is the OS that I'm running this on. Powershell V2
This is the result from running $error[0]
PS C:\Users\markdamen\desktop \Powershel l> $error[0]
Exception calling "GetHostByAddress" with "1" argument(s): "The requested protocol has not been configured into the system, or no implementation for it exists"
At C:\Users\markdamen\desktop \Powershel l\Get-Comp uterAssetI nformation .ps1:214 char:44
+ [net.dns]::GetHostByAddres s <<<< ($_)
+ CategoryInfo : NotSpecified: (:) [], MethodInvocationException
+ FullyQualifiedErrorId : DotNetMethodException
This is the result from running $error[0]
PS C:\Users\markdamen\desktop
Exception calling "GetHostByAddress" with "1" argument(s): "The requested protocol has not been configured into the system, or no implementation for it exists"
At C:\Users\markdamen\desktop
+ [net.dns]::GetHostByAddres
+ CategoryInfo : NotSpecified: (:) [], MethodInvocationException
+ FullyQualifiedErrorId : DotNetMethodException
SOLUTION
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
ASKER
OK - with the script that you posted, I can't get past this error:
This is the output from the original script, with -verbose parameter.
PS C:\Users\markdamen\Desktop \Powershel l> . .\Get-ComputerAssetInforma tion_v2.ps 1
Missing closing ')' in expression.
At C:\Users\markdamen\Desktop \Powershel l\Get-Comp uterAssetI nformation _v2.ps1:32 6 char:1
+ <<<<
+ CategoryInfo : ParserError: (CloseParenToken:TokenId) [], ParseException
+ FullyQualifiedErrorId : MissingEndParenthesisInExp ression
Missing closing ')' in expression.
At C:\Users\markdamen\Desktop
+ <<<<
+ CategoryInfo : ParserError: (CloseParenToken:TokenId) [], ParseException
+ FullyQualifiedErrorId : MissingEndParenthesisInExp
This is the output from the original script, with -verbose parameter.
PS C:\Users\markdamen\Desktop \Powershel l> Get-ComputerAssetInformati on -ComputerName martin-pc -verbose
VERBOSE: Creating local hostname list
VERBOSE: Creating initial variables
VERBOSE: Creating Initial Session State
VERBOSE: Adding variable runspacetimers to initial session state
VERBOSE: Adding variable Credential to initial session state
VERBOSE: Adding variable LocalHost to initial session state
VERBOSE: Creating runspace pool
VERBOSE: Defining background runspaces scriptblock
VERBOSE: Starting martin-pc
WARNING: martin-pc: Unable to index into an object of type System.Management.Automati on.PSObjec t.
VERBOSE: Thread done for martin-pc
VERBOSE: Removing martin-pc from runspaces
VERBOSE: Closing runspace pool
PS C:\Users\markdamen\Desktop \Powershel l>
VERBOSE: Creating local hostname list
VERBOSE: Creating initial variables
VERBOSE: Creating Initial Session State
VERBOSE: Adding variable runspacetimers to initial session state
VERBOSE: Adding variable Credential to initial session state
VERBOSE: Adding variable LocalHost to initial session state
VERBOSE: Creating runspace pool
VERBOSE: Defining background runspaces scriptblock
VERBOSE: Starting martin-pc
WARNING: martin-pc: Unable to index into an object of type System.Management.Automati
VERBOSE: Thread done for martin-pc
VERBOSE: Removing martin-pc from runspaces
VERBOSE: Closing runspace pool
PS C:\Users\markdamen\Desktop
I can only guess that something didn't get copied right for you. I just copied the code from my post above into a console and it ran without error.
ASKER CERTIFIED SOLUTION
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
ASKER
Didn't get an actual resolution, but learnt a couple of new techniques for error checking.
ASKER