HardwareManagement.psm1
# Copyright (c) Microsoft Corporation. All rights reserved. # For personal use only. Provided AS IS and WITH ALL FAULTS. # # HardwareManagement cmdlets #region Cached Items $ProfileCache = @{} $InteropCache = @{} $ComputerEPRCache = @{} $PCSVEPRCache = @{} #endregion #region Helper Functions function New-CustomObject ([string] $typeName, [string[]] $propertyNames) { $Object = New-Object System.Management.Automation.PSObject $Object.PSObject.TypeNames[0] = $typeName foreach ($property in $propertyNames) { $Object | Add-Member -MemberType NoteProperty -Name $property -Value $null } $Object } # Profile Registration Profile allows for both scoping and central methodology # This function abstracts the discovery logic. Function takes in a Profile instance and resulting classname function Get-CentralInstance { param ( [Parameter(ParameterSetName="CimInstance",Position=0,Mandatory=$true,ValueFromPipeline=$true)][Microsoft.Management.Infrastructure.CimInstance] $Profile, [Parameter(Mandatory=$true)][string] $resultClassName) process { $target = $null # first, see if target instance is associated directly to profile $target = $Profile | Get-CimAssociatedInstance -ResultClassName $resultClassName # else, traverse profiles to find CIM_ComputerSystem instance and then target instance while ($target -eq $null) { foreach ($relatedProfile in $Profile | Get-CimAssociatedInstance -ResultClassName CIM_RegisteredProfile) { $computerSystem = $relatedProfile | Get-CimAssociatedInstance -ResultClassName CIM_ComputerSystem if ($computerSystem) { $target = $computerSystem | Get-CimAssociatedInstance -ResultClassName $resultClassName if ($target) { break } } } } $target } } function Get-CimReferencedInstance { param ( [Parameter(ParameterSetName="CimInstance",Position=0,Mandatory=$true,ValueFromPipeline=$true)][Microsoft.Management.Infrastructure.CimInstance] $InputObject, [Microsoft.Management.Infrastructure.CimSession] $CimSession, [string] $ResultClassName = $null, [switch] $KeysOnly = $false) process { $opt = New-Object Microsoft.Management.Infrastructure.Options.CimOperationOptions if ($KeysOnly) { $opt.KeysOnly = $true } if ($ResultClassName.Length -eq 0) { [NullString] $ResultClassName = [NullString]::Value } if ($CimSession -eq $null) { $CimSession = Get-CimSession -InstanceId $InputObject.GetCimSessionInstanceId() if ($CimSession -eq $null) { Write-Error "CimSession missing" } } try { $CimSession.EnumerateReferencingInstances($InputObject.CimClass.CimSystemProperties.Namespace, $InputObject, $ResultClassName, [NullString]::Value, $opt) } catch [Microsoft.Management.Infrastructure.CimException] { # if we get this error, it means the managed node doesn't support this and we just return no instances if ($_.FullyQualifiedErrorId -ne "BadEnumeration") { throw $_ } } } } # store interop namespace and registered profiles per cimsession instanceId # since a single computer may have a BMC, we can't use the computer name as the key # this will result in duplicate cache entries for the same managed node if multiple cimsessions point to it # TODO: expire cache entries after sometime not being used function Update-Cache { param ( [Parameter(Position=0,Mandatory=$true)] [Microsoft.Management.Infrastructure.CimSession] $CimSession) process { $ErrorActionPreference = "SilentlyContinue" if ($ProfileCache.ContainsKey($CimSession.InstanceId)) { $ProfileCache.Remove($CimSession.InstanceId) $InteropCache.Remove($CimSession.InstanceId) } Write-Progress -Activity "Caching data from $($CimSession.ComputerName)" -CurrentOperation "CIM_RegisteredProfile" $foundInterop = $false # Note: Per DSP1033, I should really only need to check interop and root/interop, the managed node just needs to accept a preceded slash $interopNamespaces = "interop","root/interop","/interop","/root/interop" foreach ($ns in $interopNamespaces) { try { $profiles = Get-CimInstance -CimSession $cimsession CIM_RegisteredProfile -Namespace $ns -ErrorAction Stop $foundInterop = $true $InteropCache.Add($CimSession.InstanceId, $ns) break } catch [Microsoft.Management.Infrastructure.CimException] { if ($_.Exception.HResult -eq 0x80131500) { #InvalidSelector fault continue } else { throw $_ } } } if (-not $foundInterop) { write-warning "Target system $($CimSession.ComputerName) does not support interop namespace" return } $ProfileCache.Add($CimSession.InstanceId, $profiles) # find the CIM_ComputerSystem instance whether Central or Scoping Class methodology is used # to simplify, we assume there is only one CIM_ComputerSystem instance we want to manage per managed node # traverse each profile until one is associated to CIM_ComputerSystem # we want to use assoc filter if supported to reduce network, but will fall back to simple assoc traversal # and filter on the client #TODO: Support multi-blade systems that return multiple instances of CIM_ComputerSystem #TODO: Support returning CIM_ComputerSystem associated to specific CIM_RegisteredProfile $opt = New-Object Microsoft.Management.Infrastructure.Options.CimOperationOptions $opt.KeysOnly = $true $pcsvp = $profiles | ? {$_.RegisteredName -eq 'Physical Computer System View'} if ($pcsvp) { Write-Verbose "$($CimSession.ComputerName) supports Physical Computer System View Profile" $pcsv = $pcsvp | Get-CimAssociatedInstance -Association "CIM_ElementConformsToProfile" -ResultClassName "CIM_PhysicalComputerSystemView" -KeyOnly $PCSVEPRCache.Add($CimSession.InstanceId, $pcsv) } Write-Progress -Activity "Caching data from $($CimSession.ComputerName)" -CurrentOperation "CIM_ComputerSystem" $foundComputer = $false foreach ($profile in $profiles) { $cs = $profile | Get-CimAssociatedInstance -Association "CIM_ElementConformsToProfile" -ResultClassName "CIM_ComputerSystem" -KeyOnly if ($cs -ne $null) { $ComputerEPRCache.Add($CimSession.InstanceId, $cs) $foundComputer = $true break } } if (-not $foundComputer) { Write-Warning "Could not find instance of CIM_ComputerSystem on $($CimSession.ComputerName)" } Write-Progress -Activity "Caching data from $($CimSession.ComputerName)" -Completed } } function Get-CacheComputerSystem ([Microsoft.Management.Infrastructure.CimSession] $CimSession, [switch] $PCSV = $false) { if (-not $InteropCache.ContainsKey($CimSession.InstanceId)) { Update-Cache $CimSession } # Need to retrieve it each time since actual instance properties may have changed if (-not $PCSV -and $ComputerEPRCache.ContainsKey($CimSession.InstanceId)) { Write-Verbose "Using Computer System Profile" $computerSystem = Get-CimInstance -CimSession $CimSession $ComputerEPRCache[$CimSession.InstanceId] $computerSystem.pstypenames.insert(0,"Microsoft.Management.Infrastructure.CimInstance#CIM_ComputerSystem") $computerSystem } elseif ($PCSVEPRCache.ContainsKey($CimSession.InstanceId)) { Write-Verbose "Using Physical Computer System View Profile" $computerSystem = Get-CimInstance -CimSession $CimSession $PCSVEPRCache[$CimSession.InstanceId] $computerSystem.pstypenames.insert(0,"Microsoft.Management.Infrastructure.CimInstance#CIM_ComputerSystem") $computerSystem } } function New-Enum ([string] $namespace, [string] $name, [string[]] $members) { $code = @" namespace $namespace { public enum $name : int { $($members -join ",`n") } } "@ Add-Type $code } function Get-ValueFromMap{ param ( [string[]] $values, [int[]] $valueMap, [int] $value) process { $valueHashTable = @{} for($i = 0; $i -lt $values.Length; $i++) { $valueHashTable.Add($valueMap[$i], $values[$i]) } if (-not $valueHashTable.Contains($value)) { return $value.ToString() + ":Undefined" } return $($valueHashTable[$value]) } } function Get-ValueFromIndex([string[]] $values, [int] $value, [switch] $noValueNum, [switch] $noZero) { if ($value -eq 0 -and $noZero) { return } if (-not $noValueNum) { $valueNum = $value.ToString() + ":" } if ($value -gt $values.Length) { return "Undefined" } else { return $values[$value] } } #endregion #region General CIM Profiles function Get-RegisteredProfile { <# .Synopsis Returns CIM Profiles registered on the managed node .Description Returns instances of CIM_RegisteredProfile registered on the managed node based on the Profile Registration Profile. More details of the Profile Registration Profile can be found here: http://www.dmtf.org/standards/published_documents/DSP1033_1.0.pdf .Parameter CimSession Instance or array of instances of existing CimSession objects. See New-CimSession help for details. .Parameter RegisteredName Find instances only matching the RegisteredName property such as "Base Desktop and Mobile". .Parameter RegisteredVersion Find instances only matching the RegisteredVersion property, "1.0" would match "1.0.0" as well as "1.0.1" .Parameter RegisteredOrganization Find instances only matching the RegisteredOrganization or OtherRegisteredOrganization property such as "DMTF" .Example PS C:\> # Create new CimSession to out-of-band DASH capable hardware using HTTP and Digest PS C:\> $comp1 = New-CimSession -ComputerName comp1 -Authentication Digest -Credential $cred -port 623 PS C:\> # Create another CimSession to out-of-band DASH capable hardware using HTTPS and Basic PS C:\> $comp2 = New-CimSession -ComputerName comp2 -Authentication Basic -Credential $cred2 -port 664 PS C:\> Get-RegisteredProfile -CimSession $comp1,$comp2 -RegisteredName "Base Desktop and Mobile" -RegisteredOrganization "DMTF" RegisteredName RegisteredOrganization OtherRegisteredOrganization Registered PSComputerName Version -------------- ---------------------- --------------------------- ---------- -------------- Base Desktop and Mobile DMTF 1.0.0 comp1 Base Desktop and Mobile DMTF 1.0.0 comp2 #> [CmdletBinding()] param ( [Parameter(Position=0)][string] $RegisteredName, [Parameter(Position=1)][string] $RegisteredVersion, [Parameter(Position=2)][string] $RegisteredOrganization, [Microsoft.Management.Infrastructure.CimSession[]] $CimSession = ".") process { foreach ($system in $CimSession) { if (-not $ProfileCache.ContainsKey($system.InstanceId)) { Update-Cache $system } foreach($profile in $ProfileCache[$system.InstanceId]) { if ($RegisteredName -eq [String]::Empty -or $profile.RegisteredName -eq $RegisteredName) { if ($RegisteredVersion -eq [String]::Empty -or $profile.RegisteredVersion -match $RegisteredVersion) { if ($RegisteredOrganization -eq [String]::Empty -or $profile.RegisteredOrganizationName -match $RegisteredOrganization ` -or $profile.OtherRegisteredOrganization -match $RegisteredOrganization -or ($profile.RegisteredOrganization -eq 2 ` -and $RegisteredOrganization -match "DMTF")) { # explicitly add type in case returned instance is derived so that formatting is applied $profile.pstypenames.insert(0,"Microsoft.Management.Infrastructure.CimInstance#CIM_RegisteredProfile") $profile } } } } } } } #endregion #region Hardware Profiles . New-Enum CIM PowerState "On","SleepLight","SleepDeep","PowerCycleSoft","OffHard","Hibernate","OffSoft", ` "PowerCycleHard","MasterBusReset","DiagnosticInterrupt","OffSoftGraceful","OffHardGraceful", ` "MasterBusResetGraceful","PowerCycleSoftGraceful","PowerCycleHardGraceful" function Get-PowerState { <# .Synopsis Returns current power state for target object .Description Returns current power state of a CIM object if the managed endpoint supports the Power State Management Profile. More details of the Power State Management Profile can be found here: http://dmtf.org/sites/default/files/standards/documents/DSP1027_1.0.pdf .Parameter CimSession Instance or array of instances of existing CimSession objects. See New-CimSession help for details. .Parameter TargetObject Instance to a specific CIM object that supports Power State Management. If not supplied, the Computer System power state is returned with the CIM_ComputerSystem instance .Example PS C:\> # Create new CimSession to out-of-band DASH capable hardware using HTTP and Digest PS C:\> $comp1 = New-CimSession -ComputerName comp1 -Authentication Digest -Credential $cred -port 623 PS C:\> # Create another CimSession to out-of-band DASH capable hardware using HTTPS and Basic PS C:\> $comp2 = New-CimSession -ComputerName comp2 -Authentication Basic -Credential $cred2 -port 664 PS C:\> Get-PowerState -CimSession $comp1,$comp2 Name Dedicated PowerState EnabledState AvailablePower Roles PSComputerName States ---- --------- ---------- ------------ --------- ----- -------------- e00971c5-614... Desktop Sleep-Deep Quiesce {} Managed System comp1 ManagedSystem Laptop On Enabled {On, Power ... comp2 #> [CmdletBinding(DefaultParametersetName="CimSession")] param ( [Parameter(ParameterSetName="CimSession",Position=0)] [Microsoft.Management.Infrastructure.CimInstance] $TargetObject = $null, [Parameter(ParameterSetName="CimSession")] [Microsoft.Management.Infrastructure.CimSession[]] $CimSession = ".") process { $ErrorActionPreference = "Stop" $powerStates = "Undefined", "Undefined", "On", "Sleep-Light", "Sleep-Deep", "Power Cycle (Off-Soft)", "Off-Hard", "Hibernate (Off-Soft)", "Off-Soft", "Power cycle (Off-Hard)", "Master Bus Reset", "Diagnostic Interrupt (NMI)", "Off-Soft Graceful", "Off-Hard Graceful", "Master Bus Reset Graceful", "Power Cycle off-Soft Graceful", "Power Cycle Off-Hard Graceful" if ($TargetObject -ne $null -and $CimSession.Count -gt 1) { throw "TargetObject cannot be used if multiple CimSessions are used" } foreach ($system in $CimSession) { $powerStateProfile = Get-RegisteredProfile -CimSession $system -RegisteredName "Power State Management" -RegisteredOrganization DMTF if ($powerStateProfile -eq $null) { Write-Warning "$($system.ComputerName) does not support Power State Management Profile" continue } # need to retrieve this everytime since transient properties may have changed if ($TargetObject -eq $null) { $TargetObject = Get-CacheComputerSystem $system } $namespace = $TargetObject.CimClass.CimSystemProperties.Namespace $assocPowerMgmtSvc = $system.EnumerateReferencingInstances($namespace,$TargetObject,` "CIM_AssociatedPowerManagementService",[NullString]::value) if ($assocPowerMgmtSvc -eq $null) { Write-Warning "The remote endpoint did not return CIM_AssociatedPowerManagementService" return } $availablePowerStates = @() foreach ($availableState in $assocPowerMgmtSvc.AvailableRequestedPowerStates) { $availablePowerStates += Get-ValueFromIndex $powerStates $availableState } $TargetObject | Add-Member -MemberType NoteProperty -Name AvailablePowerStates -Value $availablePowerStates #TODO: Add support for Power Utilization Management Profile: PowerUtilizationModesSuported, PowerUtilizationMode, PowerAllocationLimit $TargetObject | Add-Member -MemberType NoteProperty -Name PowerState -Value $(Get-ValueFromIndex $powerStates $assocPowerMgmtSvc.PowerState) $TargetObject # need to reset TargetObject since you can't use the same object against different systems $TargetObject = $null } } } function Set-PowerState { <# .Synopsis Request a power state change .Description Change the power state of target CIM object if the managed endpoint supports the Power State Management Profile More details of the Power State Management Profile can be found here: http://dmtf.org/sites/default/files/standards/documents/DSP1027_1.0.pdf .Parameter CimSession Instance or array of instances of existing CimSession objects. See New-CimSession help for details. .Parameter TargetObject Instance to a specific CIM object that supports Power State Management. If not supplied, the Computer System power state is changed. .Parameter PowerState The requested new power state. See [CIM.PowerState] enum for possible values .Example PS C:\> # Create new CimSession to out-of-band DASH capable hardware using HTTP and Digest PS C:\> $comp1 = New-CimSession -ComputerName comp1 -Authentication Digest -Credential $cred -port 623 PS C:\> Set-PowerState -CimSession $comp1 -PowerState OffSoft Successfully requested power state change to 'OffSoft' on comp1 #> [CmdletBinding(DefaultParametersetName="CimSession",SupportsShouldProcess=$true)] param ( [Parameter(ParameterSetName="CimSession",Position=0,Mandatory=$true)] [Microsoft.Management.Infrastructure.CimSession[]] $CimSession = ".", [Parameter()] [Microsoft.Management.Infrastructure.CimInstance] $TargetObject = $null, [Parameter(Mandatory=$true)] [CIM.PowerState] $PowerState = $null) process { $ErrorActionPreference = "Stop" $returnValueMap = "0", "1", "2", "3", "4", "5", "6", "4096", "4097", "4098", "4099" $returnValues = "Completed with No Error", "Not Supported", "Unknown or Unspecified Error", ` "Cannot complete within Timeout Period", "Failed", "Invalid Parameter", "In Use", ` "Method Parameters Checked - Job Started", "Invalid State Transition", ` "Use of Timeout Parameter Not Supported", "Busy" $powerStateValue = ([int]$powerState + 2) # map enum to CIM values, DMTF does not define values for 0 and 1 foreach ($system in $CimSession) { $powerStateProfile = Get-RegisteredProfile -CimSession $system -RegisteredName "Power State Management" -RegisteredOrganization DMTF if ($powerStateProfile -eq $null) { write-warning "$($system.ComputerName) does not support Power State Management Profile" continue } if ($TargetObject -eq $null) { $TargetObject = Get-CacheComputerSystem $system } $namespace = $TargetObject.CimClass.CimSystemProperties.Namespace if ($PSCmdlet.ShouldProcess($system.ComputerName,"RequestPowerStateChange")) { if ($Force -or $PSCmdlet.ShouldContinue("","")) { $powerMgmtSvcs = $TargetObject | Get-CimAssociatedInstance -ResultClassName "CIM_PowerManagementService" # even if multiple instances are returned, we should be able to use any to change the power state, so just use the first one # [ordered] is needed to force the provided arguments to be ordered in cases where the endpoint is doing strict validation $out = Invoke-CimMethod -CimSession $system -InputObject $powerMgmtSvcs[0] -MethodName RequestPowerStateChange ` -Arguments ([ordered]@{PowerState=$powerStateValue;ManagedElement=[ref]$TargetObject}) #TODO: handle CIM_Job case if ($out.ReturnValue -ne 0) { Write-Warning "$($system.ComputerName) returned $(Get-ValueFromMap $returnValues $returnValueMap $out.ReturnValue)" } Write-Verbose "Successfully requested power state change to '$powerState' on $($system.ComputerName)" # need to reset TargetObject since you can't use the same object against different systems } } $TargetObject = $null } } } function Get-HardwareInventory { <# .Synopsis Returns hardware inventory .Description Returns hardware inventory from the managed node based on support for Physical Asset, CPU, and System Memory Profiles More details of the Physical Asset Profile can be found here: http://www.dmtf.org/sites/default/files/standards/documents/DSP1011_1.0.pdf More details of the CPU Profile can be found here: http://dmtf.org/sites/default/files/standards/documents/DSP1022_1.0.pdf More details of the System Memory Profile can be found here: http://dmtf.org/sites/default/files/standards/documents/DSP1026_1.0.pdf .Parameter CimSession Instance or array of instances of existing CimSession objects. See New-CimSession help for details. .Parameter UseFullProfiles Switch to specify to use the DASH/SMASH Profiles instead of optimizing to use Physical Computer System View Profile (if supported). This switch should only be used for testing or troubleshooting. .Example PS C:\> # Create new CimSession to out-of-band DASH capable hardware using HTTP and Digest PS C:\> $comp1 = New-CimSession -ComputerName comp1 -Authentication Digest -Credential $cred -port 623 PS C:\> Get-HardwareInventory -CimSession $comp1 Manufacturer Model SerialNumber Tag Processor ProcessorFamily NumOfCPU NumOf TotalSystem PSComputerName Speed Cores CPUs Memory ------------ ----- ------------ --- --------- --------------- -------- ----- ----------- -------------- Fabrikam Corp Fabrikam20000 AABBCCDD F12345 3200 Fabrikam Processor Family 2 1 2147483648 comp1 PS C:\> Get-HardwareInventory -CimSession $comp1 | Format-List Manufacturer : Fabrikam Corp Model : Fabrikam20000 PackageType : Chassis/Frame SKU : ABCD1234 SerialNumber : AABBCCDD PartNumber : Tag : F12345 FRUInfoSupported : PlatformGUID : E00971C5614311E1BBD85F1FA33E082E ProcessorCurrentClockSpeed : 3200 ProcessorMaxClockSpeed : 3200 ProcessorFamily : Fabrikam Processor Family NumberOfProcessorThreads : 2 NumberOfProcessorCores : 2 NumberOfProcessors : 1 TotalSystemMemory : 2147483648 ConsumableMemory : 1876312064 PSComputerName : comp1 #> [CmdletBinding(DefaultParametersetName="CimSession")] param ( [Parameter(ParameterSetName="CimSession",Position=0)] [Microsoft.Management.Infrastructure.CimSession[]] $CimSession = ".", [switch] $UseFullProfiles = $false) process { $ErrorActionPreference = "Stop" $packageTypes = "Unknown", "Other", "Rack", "Chassis/Frame", "Cross Connect/Backplane", "Container/Frame Slot", ` "Power Supply", "Fan", "Sensor", "Module/Card", "Port/Connector", "Battery", "Processor", "Memory", ` "Power Source/Generator", "Storage Media Package (e.g., Disk or Tape Drive)", "Blade", "Blade Expansion" $cpuFamily = "Other", "Unknown", "8086", "80286", "80386", "80486", "8087", "80287", "80387", "80487", "Pentium(R) brand", "Pentium(R) Pro", "Pentium(R) II", "Pentium(R) processor with MMX(TM) technology", "Celeron(TM)", "Pentium(R) II Xeon(TM)", "Pentium(R) III", "M1 Family", "M2 Family", "Intel(R) Celeron(R) M processor", "Intel(R) Pentium(R) 4 HT processor", "K5 Family", "K6 Family", "K6-2", "K6-3", "AMD Athlon(TM) Processor Family", "AMD(R) Duron(TM) Processor", "AMD29000 Family", "K6-2+", "Power PC Family", "Power PC 601", "Power PC 603", "Power PC 603+", "Power PC 604", "Power PC 620", "Power PC X704", "Power PC 750", "Intel(R) Core(TM) Duo processor", "Intel(R) Core(TM) Duo mobile processor", "Intel(R) Core(TM) Solo mobile processor", "Intel(R) Atom(TM) processor", "Alpha Family", "Alpha 21064", "Alpha 21066", "Alpha 21164", "Alpha 21164PC", "Alpha 21164a", "Alpha 21264", "Alpha 21364", "AMD Turion(TM) II Ultra Dual-Core Mobile M Processor Family", "AMD Turion(TM) II Dual-Core Mobile M Processor Family", "AMD Athlon(TM) II Dual-Core Mobile M Processor Family", "AMD Opteron(TM) 6100 Series Processor", "AMD Opteron(TM) 4100 Series Processor", "AMD Opteron(TM) 6200 Series Processor", "AMD Opteron(TM) 4200 Series Processor", "AMD FX(TM) Series Processor", "MIPS Family", "MIPS R4000", "MIPS R4200", "MIPS R4400", "MIPS R4600", "MIPS R10000", "AMD C-Series Processor", "AMD E-Series Processor", "AMD A-Series Processor", "AMD G-Series Processor", "AMD Z-Series Processor", "SPARC Family", "SuperSPARC", "microSPARC II", "microSPARC IIep", "UltraSPARC", "UltraSPARC II", "UltraSPARC IIi", "UltraSPARC III", "UltraSPARC IIIi", "68040", "68xxx Family", "68000", "68010", "68020", "68030", "Hobbit Family", "Crusoe(TM) TM5000 Family", "Crusoe(TM) TM3000 Family", "Efficeon(TM) TM8000 Family", "Weitek", "Itanium(TM) Processor", "AMD Athlon(TM) 64 Processor Family", "AMD Opteron(TM) Processor Family", "AMD Sempron(TM) Processor Family", "AMD Turion(TM) 64 Mobile Technology", "Dual-Core AMD Opteron(TM) Processor Family", "AMD Athlon(TM) 64 X2 Dual-Core Processor Family", "AMD Turion(TM) 64 X2 Mobile Technology", "Quad-Core AMD Opteron(TM) Processor Family", "Third-Generation AMD Opteron(TM) Processor Family", "AMD Phenom(TM) FX Quad-Core Processor Family", "AMD Phenom(TM) X4 Quad-Core Processor Family", "AMD Phenom(TM) X2 Dual-Core Processor Family", "AMD Athlon(TM) X2 Dual-Core Processor Family", "PA-RISC Family", "PA-RISC 8500", "PA-RISC 8000", "PA-RISC 7300LC", "PA-RISC 7200", "PA-RISC 7100LC", "PA-RISC 7100", "V30 Family", "Quad-Core Intel(R) Xeon(R) processor 3200 Series", "Dual-Core Intel(R) Xeon(R) processor 3000 Series", "Quad-Core Intel(R) Xeon(R) processor 5300 Series", "Dual-Core Intel(R) Xeon(R) processor 5100 Series", "Dual-Core Intel(R) Xeon(R) processor 5000 Series", "Dual-Core Intel(R) Xeon(R) processor LV", "Dual-Core Intel(R) Xeon(R) processor ULV", "Dual-Core Intel(R) Xeon(R) processor 7100 Series", "Quad-Core Intel(R) Xeon(R) processor 5400 Series", "Quad-Core Intel(R) Xeon(R) processor", "Dual-Core Intel(R) Xeon(R) processor 5200 Series", "Dual-Core Intel(R) Xeon(R) processor 7200 Series", "Quad-Core Intel(R) Xeon(R) processor 7300 Series", "Quad-Core Intel(R) Xeon(R) processor 7400 Series", "Multi-Core Intel(R) Xeon(R) processor 7400 Series", "Pentium(R) III Xeon(TM)", "Pentium(R) III Processor with Intel(R) SpeedStep(TM) Technology", "Pentium(R) 4", "Intel(R) Xeon(TM)", "AS400 Family", "Intel(R) Xeon(TM) processor MP", "AMD Athlon(TM) XP Family", "AMD Athlon(TM) MP Family", "Intel(R) Itanium(R) 2", "Intel(R) Pentium(R) M processor", "Intel(R) Celeron(R) D processor", "Intel(R) Pentium(R) D processor", "Intel(R) Pentium(R) Processor Extreme Edition", "Intel(R) Core(TM) Solo Processor", "K7", "Intel(R) Core(TM)2 Duo Processor", "Intel(R) Core(TM)2 Solo processor", "Intel(R) Core(TM)2 Extreme processor", "Intel(R) Core(TM)2 Quad processor", "Intel(R) Core(TM)2 Extreme mobile processor", "Intel(R) Core(TM)2 Duo mobile processor", "Intel(R) Core(TM)2 Solo mobile processor", "Intel(R) Core(TM) i7 processor", "Dual-Core Intel(R) Celeron(R) Processor", "S/390 and zSeries Family", "ESA/390 G4", "ESA/390 G5", "ESA/390 G6", "z/Architectur base", "Intel(R) Core(TM) i5 processor", "Intel(R) Core(TM) i3 processor", "VIA C7(TM)-M Processor Family", "VIA C7(TM)-D Processor Family", "VIA C7(TM) Processor Family", "VIA Eden(TM) Processor Family", "Multi-Core Intel(R) Xeon(R) processor", "Dual-Core Intel(R) Xeon(R) processor 3xxx Series", "Quad-Core Intel(R) Xeon(R) processor 3xxx Series", "VIA Nano(TM) Processor Family", "Dual-Core Intel(R) Xeon(R) processor 5xxx Series", "Quad-Core Intel(R) Xeon(R) processor 5xxx Series", "Dual-Core Intel(R) Xeon(R) processor 7xxx Series", "Quad-Core Intel(R) Xeon(R) processor 7xxx Series", "Multi-Core Intel(R) Xeon(R) processor 7xxx Series", "Multi-Core Intel(R) Xeon(R) processor 3400 Series", "AMD Opteron(TM) 3000 Series Processor", "AMD Sempron(TM) II Processor Family", "Embedded AMD Opteron(TM) Quad-Core Processor Family", "AMD Phenom(TM) Triple-Core Processor Family", "AMD Turion(TM) Ultra Dual-Core Mobile Processor Family", "AMD Turion(TM) Dual-Core Mobile Processor Family", "AMD Athlon(TM) Dual-Core Processor Family", "AMD Sempron(TM) SI Processor Family", "AMD Phenom(TM) II Processor Family", "AMD Athlon(TM) II Processor Family", "Six-Core AMD Opteron(TM) Processor Family", "AMD Sempron(TM) M Processor Family", "i860", "i960", "Reserved (SMBIOS Extension)", "Reserved (Un-initialized Flash Content - Lo)", "SH-3", "SH-4", "ARM", "StrongARM", "6x86", "MediaGX", "MII", "WinChip", "DSP", "Video Processor", "Reserved (For Future Special Purpose Assignment)", "Reserved (Un-initialized Flash Content - Hi)" $cpuFamilyMap = "1", "2", "3", "4", "5", "6", "7", "8", "9", "10", "11", "12", "13", "14", "15", "16", "17", "18", "19", "20", "21", "24", "25", "26", "27", "28", "29", "30", "31", "32", "33", "34", "35", "36", "37", "38", "39", "40", "41", "42", "43", "48", "49", "50", "51", "52", "53", "54", "55", "56", "57", "58", "59", "60", "61", "62", "63", "64", "65", "66", "67", "68", "69", "70", "71", "72", "73", "74", "80", "81", "82", "83", "84", "85", "86", "87", "88", "96", "97", "98", "99", "100", "101", "112", "120", "121", "122", "128", "130", "131", "132", "133", "134", "135", "136", "137", "138", "139", "140", "141", "142", "143", "144", "145", "146", "147", "148", "149", "150", "160", "161", "162", "163", "164", "165", "166", "167", "168", "169", "170", "171", "172", "173", "174", "175", "176", "177", "178", "179", "180", "181", "182", "183", "184", "185", "186", "187", "188", "189", "190", "191", "192", "193", "194", "195", "196", "197", "198", "199", "200", "201", "202", "203", "204", "205", "206", "210", "211", "212", "213", "214", "215", "216", "217", "218", "219", "221", "222", "223", "224", "228", "229", "230", "231", "232", "233", "234", "235", "236", "237", "238", "239", "250", "251", "254", "255", "260", "261", "280", "281", "300", "301", "302", "320", "350", "500", "65534", "65535" foreach ($system in $CimSession) { $HWInventory = New-CustomObject -typeName "HW_HardwareInventory" -propertyNames @("Manufacturer","Model","PackageType", "SKU","Version","SerialNumber","PartNumber","AssetTag","FRUInfoSupported","PlatformGUID","ProcessorCurrentClockSpeed", "ProcessorMaxClockSpeed","ProcessorFamily","NumberOfProcessorThreads","NumberOfProcessorCores","NumberOfProcessors", "TotalSystemMemory","ConsumableMemory","PSComputerName","PSShowComputerName","MAC") $pcsvp = Get-RegisteredProfile -CimSession $system -RegisteredName "Physical Computer System View" -RegisteredVersion 1 if (-not $UseFullProfiles -and $pcsvp) { $pcsv = Get-CacheComputerSystem $system -PCSV if ($pcsvp.ImplementedFeatures -contains "DMTF:PhysicalAssetView") { $HWInventory.FRUInfoSupported = $pcsv.FRUInfoSupported $HWInventory.Manufacturer = $pcsv.Manufacturer $HWInventory.Model = $pcsv.Model $HWInventory.SKU = $pcsv.SKU $HWInventory.SerialNumber = $pcsv.SerialNumber $HWInventory.Version = $pcsv.Version $HWInventory.PartNumber = $pcsv.PartNumber } if ($pcsvp.ImplementedFeatures -contains "DMTF:CPUView") { $HWInventory.ProcessorCurrentClockSpeed = $pcsv.ProcessorCurrentClockSpeed $HWInventory.ProcessorMaxClockSpeed = $pcsv.ProcessorMaxClockSpeed $HWInventory.ProcessorFamily = $(Get-ValueFromMap $cpuFamily $cpuFamilyMap $pcsv.ProcessorFamily) $HWInventory.NumberOfProcessorThreads = $pcsv.NumberOfProcessorThreads $HWInventory.NumberOfProcessorCores = $pcsv.NumberOfProcessorCores $HWInventory.NumberOfProcessors = $pcsv.NumberOfProcessors } if ($pcsvp.ImplementedFeatures -contains "DMTF:SystemMemoryView") { [Int64]$total = $pcsv.MemoryNumberOfBlocks * $pcsv.MemoryBlockSize $HWInventory.TotalSystemMemory = $total $total = $pcsv.MemoryConsumableBlocks * $pcsv.MemoryBlockSize $HWInventory.ConsumableMemory = $total } if ($pcsvp.ImplementedFeatures -contains "DMTF:ComputerSystemView") { $index = $pcsv.IdentifyingDescriptions.IndexOf("CIM:GUID") if ($index -ge 0) { $HWInventory.PlatformGUID = $pcsv.OtherIdentifyingInfo[$index] } $index = $pcsv.IdentifyingDescriptions.IndexOf("CIM:MAC") if ($index -ge 0) { $HWInventory.MAC = $pcsv.OtherIdentifyingInfo[$index] } $index = $pcsv.IdentifyingDescriptions.IndexOf("CIM:Tag") if ($index -ge 0) { $HWInventory.AssetTag = $pcsv.OtherIdentifyingInfo[$index] } } } else { $computer = Get-CacheComputerSystem $system $assetProfile = Get-RegisteredProfile -CimSession $system -RegisteredName "Physical Asset" -RegisteredOrganization DMTF if ($assetProfile -eq $null) { Write-Warning "$($system.ComputerName) does not support Physical Asset Profile" } else { Write-Progress -Activity "Collecting Hardware Inventory..." -CurrentOperation "Physical Asset" $chassis = $computer | Get-CimAssociatedInstance -ResultClassName "CIM_Chassis" $HWInventory.Manufacturer = $chassis.Manufacturer $HWInventory.Model = $chassis.Model $HWInventory.PackageType = $(Get-ValueFromIndex $packageTypes $chassis.PackageType) $HWInventory.SKU = $chassis.SKU $HWInventory.SerialNumber = $chassis.SerialNumber $HWInventory.PartNumber = $chassis.PartNumber $HWInventory.AssetTag = $chassis.UserTracking $assetCap = $chassis | Get-CimAssociatedInstance -ResultClassName "CIM_PhysicalAssetCapabilities" $HWInventory.FRUInfoSupported = $assetCap.FRUInfoSupported $compPkg = $computer | Get-CimReferencedInstance -ResultClassName "CIM_ComputerSystemPackage" $HWInventory.PlatformGUID = $compPkg.PlatformGUID } $CPUProfile = Get-RegisteredProfile -CimSession $system -RegisteredName "CPU" -RegisteredOrganization DMTF if ($CPUProfile -eq $null) { Write-Warning "$($system.ComputerName) does not support CPU Profile" } else { Write-Progress -Activity "Collecting Hardware Inventory..." -CurrentOperation "Processor" $cpus = $computer | Get-CimAssociatedInstance -ResultClassName "CIM_Processor" $cpuCount = 0 foreach ($cpu in $cpus) { $cpuCount++ $HWInventory.ProcessorCurrentClockSpeed = $cpu.CurrentClockSpeed $HWInventory.ProcessorMaxClockSpeed = $cpu.MaxClockSpeed $HWInventory.ProcessorFamily = $(Get-ValueFromMap $cpuFamily $cpuFamilyMap $cpu.Family) $cpuCap = $cpu | Get-CimAssociatedInstance -ResultClassName "CIM_ProcessorCapabilities" $HWInventory.NumberOfProcessorThreads = $cpuCap.NumberOfHardwareThreads $HWInventory.NumberOfProcessorCores = $cpuCap.NumberOfProcessorCores break #only support homogenous main CPU } $HWInventory.NumberOfProcessors = $cpuCount } $memoryProfile = Get-RegisteredProfile -CimSession $system -RegisteredName "System Memory" -RegisteredOrganization DMTF if ($memoryProfile -eq $null) { Write-Warning "$($system.ComputerName) does not support System Memory Profile" } else { Write-Progress -Activity "Collecting Hardware Inventory..." -CurrentOperation "System Memory" $mem = $computer | Get-CimAssociatedInstance -ResultClassName "CIM_Memory" [Int64]$totalMemory = $mem.NumberOfBlocks * $mem.BlockSize $HWInventory.TotalSystemMemory = $totalMemory [Int64]$consumableMemory = $mem.ConsumableBlocks * $mem.BlockSize $HWInventory.ConsumableMemory = $consumableMemory } Write-Progress -Activity "Collecting Hardware Inventory..." -Completed } $HWInventory.PSComputerName = $system.ComputerName $HWInventory.PSShowComputerName = $true $HWInventory } } } function Get-SoftwareInventory { <# .Synopsis Returns software inventory .Description Returns software inventory from managed node based on support for Software Inventory profile For hardware devices, this typically means firmware/BIOS/EFI. More details of the Software Inventory Profile can be found here: http://dmtf.org/sites/default/files/standards/documents/DSP1023_1.0.pdf .Parameter CimSession Instance or array of instances of existing CimSession objects. See New-CimSession help for details. .Parameter UseSoftwareInventoryProfile Switch to specify to use the Software Inventory Profile instead of optimizing to use Physical Computer System View Profile (if supported). This switch should only be used for testing or troubleshooting. .Example PS C:\> # Create new CimSession to out-of-band DASH capable hardware using HTTP and Digest PS C:\> $comp1 = New-CimSession -ComputerName comp1 -Authentication Digest -Credential $cred -port 623 PS C:\> Get-SoftwareInventory -CimSession $comp1 ElementName Manufacturer VersionString PSComputerName ----------- ------------ ------------- -------------- System Firmware Information Fabrikam Corp v01.15 comp1 Management Controller Firmware Information Fabrikam Corp DASH 1.52.0.2 comp1 Network Controller Firmware Information Fabrikam Corp 3.80 comp1 Network Controller Driver Information Fabrikam Corp 15.2.0.5 comp1 #> [CmdletBinding(DefaultParametersetName="CimSession")] param ( [Parameter(ParameterSetName="CimSession",Position=0)] [Microsoft.Management.Infrastructure.CimSession[]] $CimSession = ".", [switch] $UseSoftwareInventoryProfile = $false) process { $ErrorActionPreference = "Stop" foreach ($system in $CimSession) { $pcsvp = Get-RegisteredProfile -CimSession $system -RegisteredName "Physical Computer System View" -RegisteredVersion 1 if (-not $UseSoftwareInventoryProfile -and $pcsvp -and $pcsvp.ImplementedFeatures -contains "DMTF:SoftwareInventoryView") { $pcsv = Get-CacheComputerSystem $system -PCSV if (-not $UseSoftwareInventoryProfile -and $pcsv) { Write-Verbose "Using Physical Computer System View" New-CimInstance -Namespace "" -ClassName CIM_SoftwareIdentity -ClientOnly -Property @{ SoftwareElementName="BIOS"; Classifications=@(11); ElementName="BIOS"; MajorVersion=$pcsv.CurrentBIOSMajorVersion; MinorVersion=$pcsv.CurrentBIOSMinorVersion; VersionString=$pcsv.CurrentBIOSVersionString; PSComputerName=$system.ComputerName; PSShowComputerName=$true; CimSessionInstanceID=$system.InstanceId } New-CimInstance -Namespace "" -ClassName CIM_SoftwareIdentity -ClientOnly -Property @{ SoftwareElementName="Management Firmware"; Classifications=@(10); ElementName="Management Firmware"; MajorVersion=$pcsv.CurrentManagementFirmwareMajorVersion; MinorVersion=$pcsv.CurrentManagementFirmwareMinorVersion; VersionString=$pcsv.CurrentManagementFirmwareVersionString; PSComputerName=$system.ComputerName; PSShowComputerName=$true; CimSessionInstanceID=$system.InstanceId } } } else { $computer = Get-CacheComputerSystem $system $softwareProfile = Get-RegisteredProfile -CimSession $system -RegisteredName "Software Inventory" -RegisteredOrganization DMTF if ($softwareProfile -eq $null) { Write-Warning "$($system.ComputerName) does not support Software Inventory Profile" continue } else { foreach ($software in ($computer | Get-CimAssociatedInstance -Association "CIM_InstalledSoftwareIdentity" -ResultClassName "CIM_SoftwareIdentity")) { $software.pstypenames.insert(0,"Microsoft.Management.Infrastructure.CimInstance#CIM_SoftwareIdentity") $software } } } } } } function Get-OSStatus { <# .Synopsis Returns current OS status .Description Returns current installed OS and status from managed node based on support for OS Status Profile More details of the OS Status Profile can be found here: http://dmtf.org/sites/default/files/standards/documents/DSP1029_1.0.pdf .Parameter CimSession Instance or array of instances of existing CimSession objects. See New-CimSession help for details. .Parameter UseOSStatusProfile Switch to specify to use the OS Status Profile instead of optimizing to use Physical Computer System View Profile (if supported). This switch should only be used for testing or troubleshooting. .Example PS C:\> # Create new CimSession to out-of-band DASH capable hardware using HTTP and Digest PS C:\> $comp1 = New-CimSession -ComputerName comp1 -Authentication Digest -Credential $cred -port 623 PS C:\> Get-OSStatus -CimSession $comp1 OSType Version EnabledState PSComputerName ------ ------- ------------ -------------- Microsoft Windows 7 6.1.7601 Quiesce comp1 #> [CmdletBinding(DefaultParametersetName="CimSession")] param ( [Parameter(ParameterSetName="CimSession",Position=0)] [Microsoft.Management.Infrastructure.CimSession[]] $CimSession = ".", [switch] $UseOSStatusProfile = $false) process { $ErrorActionPreference = "Stop" foreach ($system in $CimSession) { $pcsvp = Get-RegisteredProfile -CimSession $system -RegisteredName "Physical Computer System View" -RegisteredVersion 1 if (-not $UseOSStatusProfile-and $pcsvp -and $pcsvp.ImplementedFeatures -contains "DMTF:OSView") { $pcsv = Get-CacheComputerSystem $system -PCSV if (-not $UseOSStatusProfile -and $pcsv) { Write-Verbose "Using Physical Computer System View" New-CimInstance -Namespace "" -ClassName CIM_OperatingSystem -ClientOnly -Property @{ OSType=$pcsv.OSType; EnabledState=$pcsv.OSEnabledState; Version=$pcsv.OSVersion; CimSessionInstanceID=$system.InstanceId } } } else { $osProfile = Get-RegisteredProfile -CimSession $system -RegisteredName "OS Status" -RegisteredOrganization DMTF if ($osProfile -eq $null) { Write-Warning "$($system.ComputerName) does not support OS Status Profile" continue } else { $computer = Get-CacheComputerSystem $system foreach ($os in ($computer | Get-CimAssociatedInstance -Association "CIM_InstalledOS" -ResultClassName "CIM_OperatingSystem")) { $os.pstypenames.insert(0,"Microsoft.Management.Infrastructure.CimInstance#CIM_OperatingSystem") $os } } } } } } function Get-ComputerSystem { <# .Synopsis Returns computer system .Description Returns computer system from managed node based on support for Base Desktop and Mobile, Base Server, or Computer System Profiles More details of the Computer System Profile can be found here: http://www.dmtf.org/sites/default/files/standards/documents/DSP1052_1.0.pdf More details of the Base Server Profile can be found here: http://www.dmtf.org/sites/default/files/standards/documents/DSP1004_1.0.pdf More details of the Base Desktop and Mobile Profile can be found here: http://www.dmtf.org/sites/default/files/standards/documents/DSP1058_1.0.pdf .Parameter CimSession Instance or array of instances of existing CimSession objects. See New-CimSession help for details. .Parameter PCSV Switch to specify to use the Physical Computer System View Profile (PCSV) instead of DASH/SMASH Profiles. Since the Endpoint Reference (EPR) for the PCSV and CIM_ComputerSystem instances are cached, both should have similar performance, however, the CIM_ComputerSystem instance may have additional data that is not represented in PCSV. .Example PS C:\> # Create new CimSession to out-of-band DASH capable hardware using HTTP and Digest PS C:\> $comp1 = New-CimSession -ComputerName comp1 -Authentication Digest -Credential $cred -port 623 PS C:\> # Create another CimSession to out-of-band DASH capable hardware using HTTPS and Basic PS C:\> $comp2 = New-CimSession -ComputerName comp2 -Authentication Basic -Credential $cred2 -port 664 PS C:\> Get-ComputerSystem -CimSession $comp1,$comp2 Name Dedicated PowerState EnabledState AvailablePower Roles PSComputerName States ---- --------- ---------- ------------ --------- ----- -------------- e00971c5-614... Desktop Quiesce Managed System comp1 ManagedSystem Laptop Enabled comp2 #> param ( [Parameter(Position=0)] [Microsoft.Management.Infrastructure.CimSession[]] $CimSession = ".", [switch] $PCSV = $false) process { $ErrorActionPreference = "Stop" foreach ($system in $CimSession) { $baseProfile = Get-RegisteredProfile -CimSession $system -RegisteredName "Base Desktop and Mobile" -RegisteredOrganization DMTF if ($baseProfile -eq $null) { $baseProfile = Get-RegisteredProfile -CimSession $system -RegisteredName "Base Server" -RegisteredOrganization DMTF if ($baseProfile -eq $null) { $baseProfile = Get-RegisteredProfile -CimSession $system -RegisteredName "Computer System" -RegisteredOrganization DMTF if ($baseProfile -eq $null) { $baseProfile = Get-RegisteredProfile -CimSession $system -RegisteredName "Physical Computer System View" -RegisteredOrganization DMTF if ($baseProfile -eq $null) { Write-Warning "$($system.ComputerName) does not support Base Desktop and Mobile, Base Server, Computer System Profile, or Physical Computer System View Profile" continue } } } } if ($baseProfile -ne $null) { $params = @{} if ($PCSV) { $params.Add("PCSV",$true) } $computerSystem = Get-CacheComputerSystem $system @params $computerSystem } } } } function Get-NumericSensor { <# .Synopsis Returns numeric sensors .Description Returns numeric sensors supported by the managed node based on suport of Sensors Profile More information about the Sensors Profile can be found here: http://dmtf.org/sites/default/files/standards/documents/DSP1009_1.1.pdf .Parameter CimSession Instance or array of instances of existing CimSession objects. See New-CimSession help for details. .Parameter UseSensorProfile Switch to specify to use the Sensor Profile instead of optimizing to use Physical Computer System View Profile (if supported). This switch should only be used for testing or troubleshooting. .Example PS C:\> # Create new CimSession to out-of-band DASH capable hardware using HTTP and Digest PS C:\> $comp1 = New-CimSession -ComputerName comp1 -Authentication Digest -Credential $cred -port 623 PS C:\> Get-NumericSensor -CimSession $comp1,$comp2 ElementName Communication ComputedReading SensorType EnabledState PSComputerName Status ----------- ------------- --------------- ---------- ------------ -------------- Numeric Sensor #1 (Tachometer) Ok 300 RPM Tachometer Not Applicable comp1 Numeric Sensor #2 (Tachometer) Ok 300 RPM Tachometer Not Applicable comp1 Numeric Sensor #3 (Chassis Temperature) Ok 35 Degrees C Temperature Not Applicable comp1 Numeric Sensor #4 (CPU Temperature) Ok 40 Degrees C Temperature Not Applicable comp1 #> [CmdletBinding(DefaultParametersetName="CimSession")] param ( [Parameter(ParameterSetName="CimSession",Position=0)] [Microsoft.Management.Infrastructure.CimSession[]] $CimSession = ".", [switch] $UseSensorProfile = $false) process { $ErrorActionPreference = "Stop" foreach ($system in $CimSession) { $pcsvp = Get-RegisteredProfile -CimSession $system -RegisteredName "Physical Computer System View" -RegisteredVersion 1 if (-not $UseSensorProfile -and $pcsvp -and $pcsvp.ImplementedFeatures -contains "DMTF:NumericSensorView") { $pcsv = Get-CacheComputerSystem $system -PCSV Write-Verbose "Using Physical Computer System View" $sensorProperties = "BaseUnits","Context","CurrentReading","CurrentState","ElementName", "EnabledState","HealthState","LowerThresholdCritical","LowerThresholdFatal", "LowerThresholdNonCritical","OtherSensorTypeDescription","PrimaryStatus", "RateUnits","SensorType","UnitModifier","UpperThresholdCritical", "UpperThresholdFatal","UpperThresholdNonCritical" $numSensors = $pcsv.NumericSensorElementName.Count for ($index = 0; $index -lt $numSensors; $index++ ) { $cimsensor = New-CimInstance -ClassName CIM_NumericSensor -Namespace "" -ClientOnly foreach ($property in $sensorProperties) { $pcsvProperty = $pcsv.CimInstanceProperties.Item("NumericSensor" + $property) $propertyValue = $null if ($pcsvProperty.value) { $propertyValue = $pcsvProperty.Value[$index] } if ($propertyValue) { $cimProperty = [Microsoft.Management.Infrastructure.CimProperty]::Create($property, $propertyValue, 0) } else { $cimProperty = [Microsoft.Management.Infrastructure.CimProperty]::Create($property, $propertyValue, [Microsoft.Management.Infrastructure.CimType]::String, 0) } $cimsensor.CimInstanceProperties.Add($cimProperty) } $cimsensor | Add-Member -MemberType NoteProperty -Name CimSessionInstanceID -Value $system.InstanceId $cimsensor | Add-Member -MemberType NoteProperty -Name PSComputerName -Value $system.ComputerName -Force $cimsensor | Add-Member -MemberType NoteProperty -Name PSShowComputerName -Value $true -Force $cimsensor } } else { $computer = Get-CacheComputerSystem $system $sensorProfile = Get-RegisteredProfile -CimSession $system -RegisteredName "Sensors" -RegisteredOrganization DMTF if ($sensorProfile -eq $null) { Write-Warning "$($system.ComputerName) does not support Sensors Profile" continue } else { foreach ($sensor in ($computer | Get-CimAssociatedInstance -ResultClassName "CIM_NumericSensor")) { $sensor.pstypenames.insert(0,"Microsoft.Management.Infrastructure.CimInstance#CIM_NumericSensor") $sensor } } } } } } function Get-BootOrder { <# .Synopsis Returns current boot sources .Description Returns current boot sources and their defined order from managed node based on support of Boot Control Profile More details about the Boot Control Profile can be found here: http://dmtf.org/sites/default/files/standards/documents/DSP1012_1.0.pdf .Parameter CimSession Instance or array of instances of existing CimSession objects. See New-CimSession help for details. .Parameter Persistent If used, this switch will filter results to only show boot sources for setting persistent boot order. .Parameter BootString If used, the value of this parameter will be used to filter results against the StructuredBootString property. .Parameter UseBootControlProfile Switch to specify to use the Boot Control Profile instead of optimizing to use Physical Computer System View Profile (if supported). This switch should only be used for testing or troubleshooting. .Example PS C:\> # Create new CimSession to out-of-band DASH capable hardware using HTTP and Digest PS C:\> $comp1 = New-CimSession -ComputerName comp1 -Authentication Digest -Credential $cred -port 623 PS C:\> Get-BootOrder -CimSession $comp1 ElementName BootSupport AssignedSequence StructuredBootString FailThroughSupp PSComputerName orted ----------- ----------- ---------------- -------------------- --------------- -------------- Boot Order (Hard Drive) PersistentNext 2 CIM:Hard-Disk:1 Yes comp1 Boot Order (CD-ROM) PersistentNext 3 CIM:CD/DVD:2 Yes comp1 Boot Order (Network) PersistentNext 4 CIM:Network:3 No comp1 Boot Order (USB Device) PersistentNext 1 CIM:USB:4 Yes comp1 .Example PS C:\> # Create new CimSession to out-of-band DASH capable hardware using HTTP and Digest PS C:\> $comp1 = New-CimSession -ComputerName comp1 -Authentication Digest -Credential $cred -port 623 PS C:\> Get-BootOrder -CimSession $comp1 -BootString network -Persistent ElementName BootSupport AssignedSequence StructuredBootString FailThroughSupp PSComputerName orted ----------- ----------- ---------------- -------------------- --------------- -------------- Boot Order (Network) PersistentNext 4 CIM:Network:3 No comp1 #> [CmdletBinding(DefaultParametersetName="CimSession")] param ( [Parameter(ParameterSetName="CimSession",Position=0,ValueFromPipeLine=$true)] [Microsoft.Management.Infrastructure.CimSession[]] $CimSession = ".", [switch] $Persistent = $false, [string] $BootString = $null, [switch] $UseBootControlProfile = $false) process { $ErrorActionPreference = "Stop" $failThroughSupportedValues = "Unknown", "Is Supported", "Not Supported" $isNextValues = "Unknown", "Persistent", "OneTime", "OneTime" # the first OneTime means it's available to be reused for OneTime foreach ($system in $CimSession) { $pcsvp = Get-RegisteredProfile -CimSession $system -RegisteredName "Physical Computer System View" -RegisteredVersion 1 if (-not $UseBootControlProfile -and $pcsvp -and $pcsvp.ImplementedFeatures -contains "DMTF:BootControlView") { $pcsv = Get-CacheComputerSystem $system -PCSV #TODO: persistant boot order not defined yet in PCSV schema if ($Persistent) { Write-Warning "Physical Computer System View 1.0 doesn't support Persistent Boot Order. Rerun cmdlet with -UseBootControlProfile switch if supported by device" return $false } $bootStrings = $pcsv.StructuredBootString for ($i = 0; $i -lt $bootStrings.Count; $i++) { $bootsource = New-CimInstance -Namespace "" -ClassName CIM_BootSourceSetting -ClientOnly -Property @{ ElementName=$null;BootSupport="OneTime";AssignedSequence=0;StructuredBootString=$bootStrings[$i];FailThroughSupported=$null; PSComputerName=$system.ComputerName;PSShowComputerName=$true;CimSessionInstanceID=$system.InstanceId } if ($i -eq $pcsv.OneTimeBootSource) { $bootsource.AssignedSequence=1 } $bootsource } } else { $bootProfile = Get-RegisteredProfile -CimSession $system -RegisteredName "Boot Control" -RegisteredOrganization DMTF if ($bootProfile -eq $null) { write-warning "$($system.ComputerName) does not support Boot Control Profile" continue } $computer = Get-CacheComputerSystem $system $bootService = $computer | Get-CimAssociatedInstance -Association "CIM_HostedService" -ResultClassName "CIM_BootService" $bootConfigSettings = $computer | Get-CimAssociatedInstance -ResultClassName "CIM_BootConfigSetting" foreach ($bootConfigSetting in $bootConfigSettings) { $bootOrderedComponents = $bootConfigSetting | Get-CimReferencedInstance -ResultClassName "CIM_OrderedComponent" try { $bootSources = $bootConfigSetting | Get-CimAssociatedInstance -ResultClassName "CIM_BootSourceSetting" } catch [Microsoft.Management.Infrastructure.CimException] { # if we get this error, it means the managed node doesn't support this, we'll just not use that instance if ($_.FullyQualifiedErrorId -ne "HRESULT 0x8033801a,Microsoft.Management.Infrastructure.CimCmdlets.GetCimAssociatedInstanceCommand") { throw $_ } continue } $elementSettingData = $bootConfigSetting | Get-CimReferencedInstance -ResultClassName "CIM_ElementSettingData" $isNext = Get-ValueFromIndex $isNextValues $elementSettingData.IsNext $index = 0 :EnumerateBootSources foreach ($bootSource in $bootSources) { if ($Persistent -eq $true -and $elementSettingData.IsNext -ne 1) { $index++ continue EnumerateBootSources; } if ($bootString.Length -gt 0 -and $bootSource.StructuredBootString -inotlike $bootString) { $index++ continue EnumerateBootSources; } $bootSource | Add-Member -MemberType NoteProperty -Name BootSupport -Value $isNext $bootSource | Add-Member -MemberType NoteProperty -Name AssignedSequence -Value $bootOrderedComponents[$index].AssignedSequence $bootSource.pstypenames.insert(0,"Microsoft.Management.Infrastructure.CimInstance#CIM_BootSourceSetting") $bootSource $index++ } } } } } } function Set-BootOrder { <# .Synopsis Set boot order .Description Set persistant or next boot order for managed node based on support of Boot Control Profile More details about the Boot Control Profile can be found here: http://dmtf.org/sites/default/files/standards/documents/DSP1012_1.0.pdf .Parameter CimSession Instance or array of instances of existing CimSession objects. See New-CimSession help for details. .Parameter BootOrder Ordered array of CIM_BootSourceSetting instances returned from Get-BootOrder .Parameter OneTime Use of this switch will set a single CIM_BootSourceSetting to use for next boot. If this switch is not used, the supplied order is persisted. .Parameter UseBootControlProfile Switch to specify to use the Boot Control Profile instead of optimizing to use Physical Computer System View Profile (if supported). This switch should only be used for testing or troubleshooting. .Example Change persistent boot order PS C:\> # Create new CimSession to out-of-band DASH capable hardware using HTTP and Digest PS C:\> $comp1 = New-CimSession -ComputerName comp1 -Authentication Digest -Credential $cred -port 623 PS C:\> $bootSources = Get-BootOrder -CimSession $comp1 PS C:\> $bootSources ElementName BootSupport AssignedSequence StructuredBootString FailThroughSupp PSComputerName orted ----------- ----------- ---------------- -------------------- --------------- -------------- Boot Order (Hard Drive) PersistentNext 2 CIM:Hard-Disk:1 Yes comp1 Boot Order (CD-ROM) PersistentNext 1 CIM:CD/DVD:2 Yes comp1 Boot Order (Network) PersistentNext 4 CIM:Network:3 No comp1 Boot Order (USB Device) PersistentNext 3 CIM:USB:4 Yes comp1 # Change order to USB, Hard Drive, CD-COM, then Network PS C:\> Set-BootOrder -CimSession $comp1 -BootOrder $bootSources[3],$bootSources[0],$bootsources[1],$bootSources[2] ElementName BootSupport AssignedSequence StructuredBootString FailThroughSupp PSComputerName orted ----------- ----------- ---------------- -------------------- --------------- -------------- Boot Order (Hard Drive) PersistentNext 2 CIM:Hard-Disk:1 Yes comp1 Boot Order (CD-ROM) PersistentNext 3 CIM:CD/DVD:2 Yes comp1 Boot Order (Network) PersistentNext 4 CIM:Network:3 No comp1 Boot Order (USB Device) PersistentNext 1 CIM:USB:4 Yes comp1 #> [CmdletBinding(DefaultParametersetName="CimSession",SupportsShouldProcess=$true)] param ( [Parameter(ParameterSetName="CimSession",Position=0)] [Microsoft.Management.Infrastructure.CimSession] $CimSession = ".", [Parameter(Mandatory=$true)] [Microsoft.Management.Infrastructure.CimInstance[]] $bootOrder, [Switch]$OneTime = $false, [Switch]$UseBootControlProfile = $false) # TODO: add $bootSource parameterset for enum values: Hard-Disk, CD/DVD, Network, USB, etc... # TODO: add support for structured boot string process { $returnValues = "Completed with No Error", "Not Supported", "Unknown/Unspecified Error", "Busy", "Invalid Reference", "Invalid Parameter", "Access Denied" $errorActionPreference = "stop" foreach ($system in $CimSession) { $pcsvp = Get-RegisteredProfile -CimSession $system -RegisteredName "Physical Computer System View" -RegisteredVersion 1 if (-not $UseBootControlProfile -and $pcsvp -and $pcsvp.ImplementedFeatures -contains "DMTF:BootControlView") { $pcsv = Get-CacheComputerSystem $system -PCSV #TODO: persistant boot order not defined yet in PCSV schema if (-not $OneTime) { Write-Error "Physical Computer System View 1.0 doesn't support Persistent Boot Order. Rerun cmdlet with -UseBootControlProfile switch if supported by device" } if ($bootOrder.Count -ne 1) { Write-Error "Only one BootSource can be provided for OneTime boot" } if ($PSCmdlet.ShouldProcess($system.ComputerName,"SetOneTimeBoot")) { if ($Force -or $PSCmdlet.ShouldContinue("","")) { $out = Invoke-CimMethod -InputObject $pcsv -MethodName SetOneTimeBootSource -Arguments @{StructuredBootString=$bootOrder.StructuredBootString} if ($out.ReturnValue -eq 0) { Write-Verbose "Command completed successfully." } elseif ($out.ReturnValue -eq 4096) { # TODO: support CIM_Job } else { Write-Warning "$($system.ComputerName) returned $(Get-ValueFromIndex -values $returnValues -value $out.returnValue)" continue } } } } else { $bootProfile = Get-RegisteredProfile -CimSession $system -RegisteredName "Boot Control" -RegisteredOrganization DMTF if ($bootProfile -eq $null) { Write-Warning "$($system.ComputerName) does not support Boot Control Profile" continue } $comp = Get-ComputerSystem $system $bootSvc = $comp | Get-CimAssociatedInstance -ResultClassName "CIM_BootService" # to see if the managed node supports changing the boot order, we need to check two things: # 1. if CIM_BootServiceCapabilities exists and BootConfigCapabilities property does not contain a 6 # 2. if CIM_BootServiceCapabilities does not exist # TODO: We'll skip this since we can just try and fail $bootConfigSetting = $null $targetIsNext = 1 # Is Next if ($OneTime) { $targetIsNext = 3 # Is Next For Single Use } # find config for next boot # we do it in a roundabout way since CIM_ComputerSystem may be associated to many elements via CIM_ElementSettingData # but we only want instances of type CIM_BootConfigSetting where CIM_ElementSettingData indicates it is next $nextBootConfig = $null $bcs = $comp | Get-CimAssociatedInstance -ResultClassName "CIM_BootConfigSetting" $esd = $bcs | Get-CimReferencedInstance -ResultClassName "CIM_ElementSettingData" foreach ($bootElementSettingData in $esd) { if ($bootElementSettingData.IsNext -eq $targetIsNext) { $nextBootConfig = Get-CimInstance $bootElementSettingData.SettingData -CimSession $system break } } if ($nextBootConfig -eq $null) { # if none found, try modifying instance of CIM_ElementSettingData where IsNext=2 to 1 or 3 as needed foreach ($bootElementSettingData in $esd) { $bootElementSettingData.IsNext = $targetIsNext Set-CimInstance $bootElementSettingData -ErrorAction SilentlyContinue if ($?) { # successful $nextBootConfig = Get-CimInstance $bootElementSettingData.SettingData -CimSession $system } break # whether we were able to set to 2 or 3, we will just try since different implementations seem to act differ } } if ($nextBootConfig -eq $null) { Write-Warning "$($system.ComputerName) does not contain appropriate instance of boot config needed" continue } $bootSourceEPRs = @() foreach ($bootSource in $bootOrder) { $bootSourceEPRs += [ref]($bootSource) } if ($PSCmdlet.ShouldProcess($system.ComputerName,"ChangeBootOrder")) { if ($Force -or $PSCmdlet.ShouldContinue("","")) { $out = Invoke-CimMethod -CimSession $system -InputObject $nextBootConfig -MethodName ChangeBootOrder -Arguments @{Source=$bootSourceEPRs} if ($out.ReturnValue -eq 0) { Write-Verbose "Command completed successfully." } elseif ($out.ReturnValue -eq 4096) { # TODO: support CIM_Job } else { Write-Warning "$($system.ComputerName) returned $(Get-ValueFromIndex -values $returnValues -value $out.returnValue)" continue } } } } } } } function Get-RecordLog { <# .Synopsis Returns record logs .Description Returns record logs from managed node based on support of Record Log Profile More details about the Record Log Profile can be found here: http://www.dmtf.org/sites/default/files/standards/documents/DSP1010_1.0.pdf http://www.dmtf.org/sites/default/files/standards/documents/DSP1010_2.0.pdf .Parameter CimSession Instance or array of instances of existing CimSession objects. See New-CimSession help for details. .Parameter InstanceId Filter results to a specific record log with this InstanceId .Parameter UseRecordLogProfile Switch to specify to use the Record Log Profile instead of optimizing to use Physical Computer System View Profile (if supported). This switch should only be used for testing or troubleshooting. .Example PS C:\> # Create new CimSession to out-of-band DASH capable hardware using HTTP and Digest PS C:\> $comp1 = New-CimSession -ComputerName comp1 -Authentication Digest -Credential $cred -port 623 PS C:\> Get-RecordLog -CimSession $comp1,$comp2 ElementName CurrentNumber MaxNumber EnabledState OverwritePolicy PSComputerName OfRecords OfRecords ----------- ------------- --------- ------------ --------------- -------------- Event Log 1 499 Enabled WrapsWhenFull comp1 #> param ( [Parameter(Position=0)] [Microsoft.Management.Infrastructure.CimSession[]] $CimSession = ".", [string] $InstanceId, [switch] $UseRecordLogProfile = $false) process { $ErrorActionPreference = "Stop" foreach ($system in $CimSession) { $pcsvp = Get-RegisteredProfile -CimSession $system -RegisteredName "Physical Computer System View" -RegisteredVersion 1 if (-not $UseRecordLogProfile -and $pcsvp -and $pcsvp.ImplementedFeatures -contains "DMTF:RecordLogView") { $pcsv = Get-CacheComputerSystem $system -PCSV if (-not $UseRecordLogProfile -and $pcsv) { Write-Verbose "Using Physical Computer System View" $LogProperties = "InstanceID","MaxNumberOfRecords","CurrentNumberOfRecords","OverwritePolicy","State" $numLogs = $pcsv.LogInstanceID.Count for ($index = 0; $index -lt $numLogs; $index++ ) { if ($InstanceId -eq "" -or ($InstanceId -eq $pcsv.LogInstanceID[$index])) { $cimLog = New-CimInstance -ClassName CIM_RecordLog -ClientOnly foreach ($property in $LogProperties) { $pcsvProperty = $pcsv.CimInstanceProperties.Item("Log" + $property) $propertyValue = $null if ($pcsvProperty.value) { $propertyValue = $pcsvProperty.Value[$index] } if ($propertyValue) { $cimProperty = [Microsoft.Management.Infrastructure.CimProperty]::Create($property, $propertyValue, 0) } else { $cimProperty = [Microsoft.Management.Infrastructure.CimProperty]::Create($property, $propertyValue, [Microsoft.Management.Infrastructure.CimType]::String, 0) } $cimLog.CimInstanceProperties.Add($cimProperty) } $cimLog | Add-Member -MemberType NoteProperty -Name CimSessionInstanceID -Value $system.InstanceId $cimLog | Add-Member -MemberType NoteProperty -Name PSComputerName -Value $system.ComputerName -Force $cimLog | Add-Member -MemberType NoteProperty -Name PSShowComputerName -Value $true -Force $cimLog } } } } else { $recordLogProfile = Get-RegisteredProfile -CimSession $system -RegisteredName "Record Log" -RegisteredVersion 1 -RegisteredOrganization DMTF if ($recordLogProfile -eq $null) { Write-Warning "$($system.ComputerName) does not support Record Log Profile" continue } else { $namespace = $recordLogProfile.CimClass.CimSystemProperties.Namespace foreach ($recordLog in ($recordLogProfile | Get-CimAssociatedInstance -Association "CIM_ElementConformsToProfile" -ResultClassName "CIM_RecordLog")) { if ($InstanceId -eq "" -or ($InstanceId -eq $recordLog.InstanceID)) { $recordLog.pstypenames.insert(0,"Microsoft.Management.Infrastructure.CimInstance#CIM_RecordLog") $recordLog } } } } } } } function Clear-RecordLog { <# .Synopsis Clears a record log .Description Removes all entries from a specific record log from managed node based on support of Record Log Profile More details about the Record Log Profile can be found here: http://www.dmtf.org/sites/default/files/standards/documents/DSP1010_1.0.pdf http://www.dmtf.org/sites/default/files/standards/documents/DSP1010_2.0.pdf .Parameter CimSession Instance of an existing CimSession object. See New-CimSession help for details. .Parameter CimRecordLog Target CIM_RecordLog instance to clear .Parameter InstanceID Target CIM_RecordLog instance based on InstanceID to clear .Parameter UseRecordLogProfile Switch to specify to use the Record Log Profile instead of optimizing to use Physical Computer System View Profile (if supported). This switch should only be used for testing or troubleshooting. .Example PS C:\> # Create new CimSession to out-of-band DASH capable hardware using HTTP and Digest PS C:\> $comp1 = New-CimSession -ComputerName comp1 -Authentication Digest -Credential $cred -port 623 PS C:\> Get-RecordLog -CimSession $comp1 | Clear-RecordLog Record log 'OEM1:70.1' cleared successfully #> [CmdletBinding(DefaultParameterSetName="CimSession",SupportsShouldProcess=$true)] param ( [Parameter(ParameterSetName="CIM_RecordLog",ValueFromPipeline=$true,Position=0,Mandatory=$true)][Alias("CimLog")] [Microsoft.Management.Infrastructure.CimInstance] $CimRecordLog = $null, [Parameter(ParameterSetName="CimSession",Mandatory=$true)] [Microsoft.Management.Infrastructure.CimSession] $CimSession, [Parameter(ParameterSetName="CimSession",Mandatory=$true)] [string] $InstanceID, [switch] $UseRecordLogProfile = $false ) process { $ErrorActionPreference = "Stop" $returnValues = "No Error", "Clear operation is not supported", "Unknown Error" if ($CimSession) { if ($UseRecordLogProfile) { $CimRecordLog = Get-RecordLog -CimSession $CimSession -InstanceId $InstanceID -UseRecordLogProfile } else { $CimRecordLog = Get-RecordLog -CimSession $CimSession -InstanceId $InstanceID } } else { $CimSession = Get-CimSession -InstanceId ($CimRecordLog.GetCimSessionInstanceId()) } if ($PSCmdlet.ShouldProcess($CimRecordLog.GetCimSessionComputerName(),"ClearLog")) { if ($Force -or $PSCmdlet.ShouldContinue("","")) { $pcsvp = Get-RegisteredProfile -CimSession $Cimsession -RegisteredName "Physical Computer System View" -RegisteredVersion 1 if (-not $UseRecordLogProfile -and $pcsvp -and $pcsvp.ImplementedFeatures -contains "DMTF:RecordLogView") { $pcsv = Get-CacheComputerSystem $CimSession -PCSV if ($InstanceID -eq "") { $InstanceID = $CimRecordLog.InstanceID } $out = Invoke-CimMethod -InputObject $pcsv -MethodName ClearLog -Arguments @{InstanceID=$InstanceID} } else { $out = Invoke-CimMethod -InputObject $CimRecordLog -MethodName ClearLog } if ($out.ReturnValue -eq 0) { Write-Verbose "Record log '$($CimRecordLog.InstanceId)' cleared successfully" } else { Write-Error "$($CimRecordLog.GetCimSessionComputerName()) returned $(Get-ValueFromIndex $returnValues $out.ReturnValue)" } } } } } function Get-LogEntry { <# .Synopsis Returns log entries for a specified record log .Description Returns log entries for a specified record log based on Record Log Profile More details about the Record Log Profile can be found here: http://www.dmtf.org/sites/default/files/standards/documents/DSP1010_1.0.pdf http://www.dmtf.org/sites/default/files/standards/documents/DSP1010_2.0.pdf .Parameter CimSession Instance of an existing CimSession object. See New-CimSession help for details. .Parameter CimRecordLog Returns log entries associated to a specific instance of CIM_RecordLog .Parameter InstanceID Returns log entries associated to a specific instance of CIM_RecordLog based on InstanceID .Example PS C:\> # Create new CimSession to out-of-band DASH capable hardware using HTTP and Digest PS C:\> $comp1 = New-CimSession -ComputerName comp1 -Authentication Digest -Credential $cred -port 623 PS C:\> Get-RecordLog -CimSession $comp1 | Get-LogEntry CreationTimeStamp : 7/30/2012 11:27:47 AM ElementName : Event Log Entry 3 InstanceID : OEM1:71.1.3 LogInstanceID : OEM1:70.1 LogName : Event Log MessageArguments : Event Log MessageID : PLAT0200 OwningEntity : DMTF PerceivedSeverity : 2 RecordData : DMTF PLAT0200 Event Log 2 3 2 //OEM/implementation:CIM_RecordLog.InstanceID="OEM1:70.1" RecordFormat : string CIM_AlertIndication.OwningEntity string CIM_AlertIndication.MessageID string CIM_AlertIndication.MessageArguments[0] string CIM_AlertIndication.MessageArguments[1] string CIM_AlertIndication.MessageArguments[2] uint16 CIM_AlertIndication.PerceivedSeverity uint16 CIM_AlertIndication.AlertType uint16 CIM_AlertIndication.AlertingElementFormat string CIM_AlertIndication.AlertingManagedElement RecordID : 3 PSComputerName : comp1 #> [CmdletBinding(DefaultParameterSetName="CimSession")] param ( [Parameter(ParameterSetName="CIM_RecordLog",ValueFromPipeline=$true,Position=0,Mandatory=$true)][Alias("CimLog")] [Microsoft.Management.Infrastructure.CimInstance] $CimRecordLog = $null, [Parameter(ParameterSetName="CimSession",Mandatory=$true)] [Microsoft.Management.Infrastructure.CimSession] $CimSession, [Parameter(ParameterSetName="CimSession",Mandatory=$true)] [string] $InstanceID ) process { $ErrorActionPreference = "Stop" if ($CimSession) { $CimRecordLog = Get-RecordLog -CimSession $CimSession -InstanceId $InstanceID -UseRecordLogProfile } elseif ($CimRecordLog.CimSessionInstanceID) { $CimRecordLog = Get-RecordLog -CimSession (Get-CimSession -InstanceId $CimRecordLog.CimSessionInstanceID) -InstanceId $CimRecordLog.InstanceID -UseRecordLogProfile } foreach ($logEntry in ($CimRecordLog | Get-CimAssociatedInstance -ResultClassName "CIM_LogEntry")) { #TODO: Format log entries based on Platform Alert Message Registry $logEntry.pstypenames.insert(0,"Microsoft.Management.Infrastructure.CimInstance#CIM_LogEntry") $logEntry } } } function Get-ConsoleRedirection { <# .Synopsis Returns current console redirection configuration for managed endpoint .Description Returns current console redirection configuration for the managed endpoint supports the Text Console Redirection Profile. Depending on the hardware support, you will need to use a seperate client (Telnet or SSH, for example) to connect to the redirected console. More details of the Text Console Redirection Profile can be found here: http://dmtf.org/sites/default/files/standards/documents/DSP1024_1.0.pdf .Parameter CimSession Instance or array of instances of existing CimSession objects. See New-CimSession help for details. .Example PS C:\> # Create new CimSession to out-of-band DASH capable hardware using HTTP and Digest PS C:\> $comp1 = New-CimSession -ComputerName comp1 -Authentication Digest -Credential $cred -port 623 PS C:\> Get-ConsoleRedirection -CimSession $comp1 ElementName EnabledState Port PSComputerName ----------- ------------ ---- -------------- Text Redirection SAP for the Telnet Service Enabled but Offline 87 comp1 Text Redirection SAP for the SSH Service Disabled 57 comp1 #> [CmdletBinding(DefaultParametersetName="CimSession")] param ( [Parameter(ParameterSetName="CimSession")] [Microsoft.Management.Infrastructure.CimSession[]] $CimSession = ".") process { $ErrorActionPreference = "Stop" foreach ($system in $CimSession) { $consoleProfile = Get-RegisteredProfile -CimSession $system -RegisteredName "Text Console Redirection" -RegisteredOrganization DMTF if ($consoleProfile -eq $null) { Write-Warning "$($system.ComputerName) does not support Text Console Redirection Profile" continue } $redirectionService = $consoleProfile | Get-CentralInstance -resultClassName CIM_TextRedirectionService if ($redirectionService -eq $null) { Write-Warning "$($system.ComputerName) did not return instance of CIM_TextRedirectionService" continue } foreach ($redirectionSAP in $redirectionService | Get-CimAssociatedInstance -ResultClassName CIM_TextRedirectionSAP) { foreach ($tcpEndpoint in $redirectionSAP | Get-CimAssociatedInstance -ResultClassName CIM_TCPProtocolEndpoint) { #TODO:currently assume only one endpoint per SAP $redirectionSAP | Add-Member -MemberType NoteProperty -Name Port -Value $tcpEndpoint.PortNumber } $redirectionSAP.pstypenames.insert(0,"Microsoft.Management.Infrastructure.CimInstance#CIM_TextRedirectionSAP") $redirectionSAP } } } } #endregion #region AuthManagement function Get-Account { <# .Synopsis Returns user accounts on the target system .Description Returns user accounts if the managed endpoint supports the Simple Identity Management Profile. More details of the Simple Identity Management Profile can be found here: http://dmtf.org/sites/default/files/standards/documents/DSP1034_1.0.pdf .Parameter CimSession Instance or array of instances of an existing CimSession objects. See New-CimSession help for details. .Parameter UserID Filter results for an account matching the specified UserID .Parameter CimAccount Retrieve the current instance of the specified accounts .Example PS C:\> # Create new CimSession to out-of-band DASH capable hardware using HTTP and Digest PS C:\> $comp1 = New-CimSession -ComputerName comp1 -Authentication Digest -Credential $cred -port 623 PS C:\> Get-Account -CimSession $comp1 Name UserID EnabledState RequestedStatesSupported Role PSComputerName ---- ------ ------------ ------------------------ ---- -------------- User:1 Administrator Enabled {Enabled, Offline} {Operator Role} comp1 User:2 Operator Offline {Enabled, Offline} {Operator Role} comp1 User:3 Auditor Enabled {Enabled, Offline} {Read Only Role, Auditor Role} comp1 #> [CmdletBinding(DefaultParametersetName="UserID")] param ( [Parameter(ParameterSetName="CimSession")] [Microsoft.Management.Infrastructure.CimSession[]] $CimSession = ".", [Parameter(ParameterSetName="CimSession")] [string] $UserID, [Parameter(ParameterSetName="CimAccount",ValueFromPipeLine=$true)] [Microsoft.Management.Infrastructure.CimInstance[]] $CimAccount = $null ) process { $ErrorActionPreference = "Stop" $refresh = $false if ($CimAccount.Count -eq 0) { foreach ($system in $CimSession) { Write-Progress -Activity "Enumerating accounts from $($CimSession.ComputerName)" -CurrentOperation "CIM_Account" $simpleIdentityProfile = Get-RegisteredProfile -CimSession $system -RegisteredName "Simple Identity Management" -RegisteredOrganization DMTF if ($simpleIdentityProfile -eq $null) { Write-Warning "$($system.ComputerName) does not support Simple Identity Management Profile" continue } $accountMgmtSvc = $simpleIdentityProfile | Get-CentralInstance -ResultClassName CIM_AccountManagementService if ($accountMgmtSvc -eq $null) { Write-Warning "$($system.ComputerName) did not return CIM_AccountManagementService" continue } $rbap = Get-RegisteredProfile -CimSession $system -RegisteredName "Role Based Authorization" -RegisteredOrganization DMTF if ($rbap -eq $null) { Write-Warning "$($system.ComputerName) does not support Role Based Authorization Profile" continue } $roleMgmtSvc = $rbap | Get-CentralInstance -resultClassName CIM_RoleBasedAuthorizationService if ($roleMgmtSvc -eq $null) { Write-Warning "$($system.ComputerName) did not return CIM_RoleBasedAuthorizationService" continue } $cs = $accountMgmtSvc | Get-CimAssociatedInstance -ResultClassName CIM_ComputerSystem if ($cs -eq $null) { Write-Warning "$($system.ComputerName) did not return CIM_ComputerSystem associated to CIM_AccountManagementService" continue } $CimAccount += $cs | Get-CimAssociatedInstance -ResultClassName CIM_Account } } else { $refresh = $true } foreach ($account in $CimAccount) { if ($refresh) { $account = $account | Get-CimInstance } if ($UserID.Length -gt 0 -and $account.UserId -ne $UserID) { continue } $cap = $account | Get-CimAssociatedInstance -ResultClassName CIM_EnabledLogicalElementCapabilities if ($cap -ne $null) { $account | Add-Member -Force -MemberType NoteProperty -Name RequestedStatesSupported -Value $cap.RequestedStatesSupported } $identities = @() $roles = @() Write-Progress -Activity "Getting identity and roles for $($account.Name)" -CurrentOperation "CIM_Role" foreach ($identity in $account | Get-CimAssociatedInstance -ResultClassName CIM_Identity) { $identities += $identity.ElementName foreach ($role in $identity | Get-CimAssociatedInstance -ResultClassName CIM_Role) { $roles += $role.ElementName } } $account | Add-Member -Force -MemberType NoteProperty -Name Identity -Value $identities $account | Add-Member -Force -MemberType NoteProperty -Name Role -Value $roles $account.pstypenames.insert(0,"Microsoft.Management.Infrastructure.CimInstance#CIM_Account") $account Write-Progress -Activity "Getting identity and roles for $($account.Name)" -Completed } } } function Get-AccountMgmtService { <# .Synopsis Returns instances of the Account Management Services of the managed endpoint .Description Returns instances of the Account Management Services of the managed endpoint if the managed endpoint supports the Simple Identity Management Profile. This is only needed if the managed endpoint has different Account Management Services for different accounts (for example, IPMI vs WS-Man) More details of the Simple Identity Management Profile can be found here: http://dmtf.org/sites/default/files/standards/documents/DSP1034_1.0.pdf .Parameter CimSession Instance or array of instances of an existing CimSession objects. See New-CimSession help for details. .Example PS C:\> # Create new CimSession to out-of-band DASH capable hardware using HTTP and Digest PS C:\> $comp1 = New-CimSession -ComputerName comp1 -Authentication Digest -Credential $cred -port 623 PS C:\> Get-AccountMgmtService -CimSession $comp1 ElementName Name PSComputerName ----------- ---- -------------- Local User Account Manageme... LocalUserAccountManagementService comp1 IPMI Account Management Ser... IPMIAccountManagementService comp1 CLP Account Management Service CLPAccountManagementService comp1 #> [CmdletBinding(DefaultParametersetName="CimSession")] param ( [Parameter(ParameterSetName="CimSession")] [Microsoft.Management.Infrastructure.CimSession[]] $CimSession = ".") process { $ErrorActionPreference = "Stop" foreach ($system in $CimSession) { $simpleIdentityProfile = Get-RegisteredProfile -CimSession $system -RegisteredName "Simple Identity Management" -RegisteredOrganization DMTF if ($simpleIdentityProfile -eq $null) { Write-Warning "$($system.ComputerName) does not support Simple Identity Management Profile" continue } foreach ($accmgmtsvc in $simpleIdentityProfile | Get-CentralInstance -ResultClassName CIM_AccountManagementService) { $accmgmtsvc.pstypenames.insert(0,"Microsoft.Management.Infrastructure.CimInstance#CIM_AccountManagementService") $accmgmtsvc } } } } # internally used function function Set-AccountState { [CmdletBinding(DefaultParametersetName="CimAccount")] param ( [Parameter(ParameterSetName="CimAccount",ValueFromPipeLine=$true)] [Microsoft.Management.Infrastructure.CimInstance] $CimAccount, [int] $RequestedState) process { $returnValues = "Completed with No Error", "Not Supported", "Unknown or Unspecified Error", "Cannot complete within Timeout Period", "Failed", "Invalid Parameter", "In Use" $ErrorActionPreference = "Stop" if (-not $cimAccount.pstypenames.contains("Microsoft.Management.Infrastructure.CimInstance#CIM_Account")) { Write-Error "Only instances of type Microsoft.Management.Infrastructure.CimInstance#CIM_Account may be used" } $out = Invoke-CimMethod -InputObject $cimAccount -MethodName RequestStateChange -Arguments @{RequestedState=$RequestedState} if ($out.ReturnValue -eq 0) { Write-Verbose "Command completed successfully." } elseif ($out.ReturnValue -eq 4096) { # TODO: support CIM_Job Write-Warning "$($CimAccount.CimSystemProperties.ServerName) accepted the request and returned a CIM_Job" } else { Write-Warning "$($CimAccount.CimSystemProperties.ServerName) returned $(Get-ValueFromIndex -values $returnValues -value $out.returnValue) ($($out.returnValue))" continue } } } function Enable-Account { <# .Synopsis Enable an account on the target system .Description Requests that the state of an account be set to enabled. More details of the Simple Identity Management Profile can be found here: http://dmtf.org/sites/default/files/standards/documents/DSP1034_1.0.pdf .Parameter CimAccount Instance of an existing CIM_Account object. See Get-Account help for details. .Parameter CimSession Instance of an existing CimSession object. See New-CimSession help for details. .Parameter UserID Used with CimSession to identify a specific account .Example PS C:\> # Create new CimSession to out-of-band DASH capable hardware using HTTP and Digest PS C:\> $comp1 = New-CimSession -ComputerName comp1 -Authentication Digest -Credential $cred -port 623 PS C:\> Get-Account -CimSession $comp1 -UserId Administrator | Enable-Account #> [CmdletBinding(DefaultParametersetName="CimSession")] param ( [Parameter(ParameterSetName="CimAccount",ValueFromPipeLine=$true)] [Microsoft.Management.Infrastructure.CimInstance] $CimAccount, [Parameter(ParameterSetName="CimSession",Mandatory=$true)] [Microsoft.Management.Infrastructure.CimSession] $CimSession, [Parameter(ParameterSetName="CimSession",Mandatory=$true)] [string] $UserID ) process { $ErrorActionPreference = "Stop" if ($CimSession) { $CimAccount = Get-Account -CimSession $CimSession -UserID $UserID } if (-not $cimAccount.pstypenames.contains("Microsoft.Management.Infrastructure.CimInstance#CIM_Account")) { Write-Error "Only instances of type Microsoft.Management.Infrastructure.CimInstance#CIM_Account may be used" } Set-AccountState -CimAccount $CimAccount -RequestedState 2 } } function Disable-Account { <# .Synopsis Disable an account on the target system .Description Requests that the state of an account be set to disabled. More details of the Simple Identity Management Profile can be found here: http://dmtf.org/sites/default/files/standards/documents/DSP1034_1.0.pdf .Parameter CimAccount Instance of an existing CIM_Account object. See Get-Account help for details. .Parameter CimSession Instance of an existing CimSession object. See New-CimSession help for details. .Parameter UserID Used with CimSession to identify a specific account .Example PS C:\> # Create new CimSession to out-of-band DASH capable hardware using HTTP and Digest PS C:\> $comp1 = New-CimSession -ComputerName comp1 -Authentication Digest -Credential $cred -port 623 PS C:\> Get-Account -CimSession $comp1 -UserId Administrator | Disable-Account #> [CmdletBinding(DefaultParametersetName="CimSession")] param ( [Parameter(ParameterSetName="CimAccount",ValueFromPipeLine=$true)] [Microsoft.Management.Infrastructure.CimInstance] $CimAccount, [Parameter(ParameterSetName="CimSession",Mandatory=$true)] [Microsoft.Management.Infrastructure.CimSession] $CimSession, [Parameter(ParameterSetName="CimSession",Mandatory=$true)] [string] $UserID ) process { $ErrorActionPreference = "Stop" if ($CimSession) { $CimAccount = Get-Account -CimSession $CimSession -UserID $UserID } if (-not $cimAccount.pstypenames.contains("Microsoft.Management.Infrastructure.CimInstance#CIM_Account")) { Write-Error "Only instances of type Microsoft.Management.Infrastructure.CimInstance#CIM_Account may be used" } Set-AccountState -CimAccount $CimAccount -RequestedState 3 } } function Suspend-Account { <# .Synopsis Suspends an account on the target system .Description Requests that the state of an account be set to offline. More details of the Simple Identity Management Profile can be found here: http://dmtf.org/sites/default/files/standards/documents/DSP1034_1.0.pdf .Parameter CimAccount Instance of an existing CIM_Account object. See Get-Account help for details. .Parameter CimSession Instance of an existing CimSession object. See New-CimSession help for details. .Parameter UserID Used with CimSession to identify a specific account .Example PS C:\> # Create new CimSession to out-of-band DASH capable hardware using HTTP and Digest PS C:\> $comp1 = New-CimSession -ComputerName comp1 -Authentication Digest -Credential $cred -port 623 PS C:\> Get-Account -CimSession $comp1 -UserId Administrator | Suspend-Account #> [CmdletBinding(DefaultParametersetName="CimSession")] param ( [Parameter(ParameterSetName="CimAccount",ValueFromPipeLine=$true)] [Microsoft.Management.Infrastructure.CimInstance] $CimAccount, [Parameter(ParameterSetName="CimSession",Mandatory=$true)] [Microsoft.Management.Infrastructure.CimSession] $CimSession, [Parameter(ParameterSetName="CimSession",Mandatory=$true)] [string] $UserID ) process { $ErrorActionPreference = "Stop" if ($CimSession) { $CimAccount = Get-Account -CimSession $CimSession -UserID $UserID } if (-not $cimAccount.pstypenames.contains("Microsoft.Management.Infrastructure.CimInstance#CIM_Account")) { Write-Error "Only instances of type Microsoft.Management.Infrastructure.CimInstance#CIM_Account may be used" } Set-AccountState -CimAccount $CimAccount -RequestedState 6 } } function ConvertTo-OctetString { <# .Synopsis Converts a string to a CIM OctetString .Description Converts a string to a CIM OctetString. This should be used where in the MOF, a string property has the OctetString qualifier. More details of the OctetString qualifier and definition can be found here: http://dmtf.org/sites/default/files/standards/documents/DSP0004_2.7.pdf .Parameter String String to be converted into an OctetString .Parameter Bytes Byte array to be converted into an OctetString .Example PS C:\> $octetstring = ConvertTo-OctetString -String "Secret" #> [CmdletBinding(DefaultParametersetName="String")] param ( [Parameter(ParameterSetName="String",ValueFromPipeLine=$true)] [string] $String, [Parameter()] [byte[]] $Bytes) process { [string]$octetString = "" # length bytes not needed as this goes over WS-Man $ByteArray = $Bytes if ($String.Length -gt 0) { $encoding = New-Object System.Text.UTF8Encoding $ByteArray = $encoding.GetBytes($String) } $octetString = [System.BitConverter]::ToString($ByteArray) -replace '-','' $octetString } } function Get-MD5Hash ($string) { $hasher = [System.Security.Cryptography.MD5]::Create() [byte[]]$bytes = [System.Text.Encoding]::UTF8.GetBytes($string) ConvertTo-OctetString -Bytes $hasher.ComputeHash($bytes) } function Convert-Password ([Microsoft.Management.Infrastructure.CimInstance] $Capabilities, [string] $ClearText = "") { switch ($Capabilities.SupportedUserPasswordEncryptionAlgorithms) { $null { $UserPassword = ConvertTo-OctetString -String $clearText } 0 { $UserPassword = ConvertTo-OctetString -String $clearText } 2 { $salt = "" if ($Capabilities.UserPasswordEncryptionSalt -ne $null) { $salt = $Capabilities.UserPasswordEncryptionSalt } $UserPassword = Get-MD5Hash -string ($userId + ":" + $salt + ":" + $clearText) } default { $supportedEncryption = @() if ($Capabilities.SupportedUserPasswordEncryptionAlgorithms -eq 1) { $supportedEncryption = $Capabilities.OtherSupportedUserPasswordEncryptionAlgorithms } else { $supportedEncryption = "Unknown" } Write-Error "$($Capatiblities.CimSystemProperties.ServerName) requires a password encryption scheme not supported by this script: $([string]::Join(',',$supportedEncryption))" } } $UserPassword } function New-Account { <# .Synopsis Creates a new account on the target system .Description Creates a new account on the target system More details of the Simple Identity Management Profile can be found here: http://dmtf.org/sites/default/files/standards/documents/DSP1034_1.0.pdf .Parameter CimSession Instance or array of instances of an existing CimSession objects. See New-CimSession help for details. .Parameter UserID UserID of the new account .Parameter Password Password of the new account as a SecureString. If not specified, you will be prompted. .Parameter AccountMgmtService Only required if the target system has multiple instances of CIM_AccountManagementService. See Get-AccountMgmtService for details. .Example PS C:\> # Create new CimSession to out-of-band DASH capable hardware using HTTP and Digest PS C:\> $comp1 = New-CimSession -ComputerName comp1 -Authentication Digest -Credential $cred -port 623 PS C:\> New-Account -CimSession $comp1 -UserID Steve #> [CmdletBinding(DefaultParametersetName="CimSession")] param ( [Parameter(ParameterSetName="CimSession")] [Microsoft.Management.Infrastructure.CimSession[]] $CimSession = ".", [Parameter(Mandatory=$true)] [string]$UserID, [Parameter(Mandatory=$true)] [System.Security.SecureString]$Password, [Parameter()] [Microsoft.Management.Infrastructure.CimInstance] $AccountMgmtService ) process { $ErrorActionPreference = "Stop" $returnValueMap = 0,1,2 $returnValues = "Operation completed successfully","Operation unsupported","Failed" $clearText = (New-Object System.Management.Automation.PSCredential('user',$Password)).GetNetworkCredential().Password foreach ($system in $CimSession) { $simpleIdentityProfile = Get-RegisteredProfile -CimSession $system -RegisteredName "Simple Identity Management" -RegisteredOrganization DMTF if ($simpleIdentityProfile -eq $null) { Write-Warning "$($system.ComputerName) does not support Simple Identity Management Profile" continue } if ($AccountMgmtService -eq $null) { $AcctMgmtServices = Get-AccountMgmtService -CimSession $system if ($AcctMgmtServices -eq $null) { Write-Error "$($system.ComputerName) did not return CIM_AccountManagementService instance" } if ($AcctMgmtServices.Count -gt 1) { Write-Error "$($system.ComputerName) contains multiple instances of CIM_AccountManagementService, one must be specified with the AccountMgmtService parameter" } $AccountMgmtService = $AcctMgmtServices } $cap = $AccountMgmtService | Get-CimAssociatedInstance -ResultClassName CIM_AccountManagementCapabilities [string]$UserPassword = "" # TODO: support case where multiple algoritms are supported [int]$EncryptionAlgorithm = $cap.SupportedUserPasswordEncryptionAlgorithms $UserPassword = Convert-Password -Capabilities $cap -ClearText $clearText $newaccount = New-CimInstance -ClassName CIM_Account -ClientOnly -Property @{SystemCreationClassName="CIM_ComputerSystem"; SystemName="ManagedSystem";CreationClassName="CIM_Account"; Name=$UserID;UserID=$UserID;UserPassword=$UserPassword; UserPasswordEncryptionAlgorithm=$EncryptionAlgorithm} -Namespace $AccountMgmtService.CimSystemProperties.Namespace $cs = $AccountMgmtService | Get-CimAssociatedInstance -ResultClassName CIM_ComputerSystem $out = Invoke-CimMethod -InputObject $AccountMgmtService -MethodName CreateAccount -Arguments @{System=[ref]$cs;AccountTemplate=$newaccount} if ($out.ReturnValue -eq 0) { $out.Account | Get-CimInstance | Get-Account } else { Write-Error "$($system.ComputerName) returned $(Get-ValueFromMap $returnValues $returnValueMap $out.ReturnValue)" } } } } function Set-Account { <# .Synopsis Set account properties on the target system .Description Set account properties. Currently, only updating the password is supported. More details of the Simple Identity Management Profile can be found here: http://dmtf.org/sites/default/files/standards/documents/DSP1034_1.0.pdf .Parameter CimAccount Instance of an existing CIM_Account object. See Get-Account help for details. .Parameter Password New password as a SecureString. If not specified, you will be prompted. .Parameter CimSession Instance of an existing CimSession object. See New-CimSession help for details. .Parameter UserID UserID of the specific account. .Example PS C:\> # Create new CimSession to out-of-band DASH capable hardware using HTTP and Digest PS C:\> $comp1 = New-CimSession -ComputerName comp1 -Authentication Digest -Credential $cred -port 623 PS C:\> Get-Account -CimSession $comp1 -UserId Administrator | Disable-Account #> [CmdletBinding(DefaultParametersetName="CimSession")] param ( [Parameter(ParameterSetName="CimAccount",ValueFromPipeLine=$true)] [Microsoft.Management.Infrastructure.CimInstance] $CimAccount, [Parameter(Mandatory=$true)] [System.Security.SecureString]$Password, [Parameter(ParameterSetName="CimSession",Mandatory=$true)] [Microsoft.Management.Infrastructure.CimSession] $CimSession, [Parameter(ParameterSetName="CimSession",Mandatory=$true)] [string] $UserID ) process { $ErrorActionPreference = "Stop" if (-not $cimAccount.pstypenames.contains("Microsoft.Management.Infrastructure.CimInstance#CIM_Account")) { Write-Error "Only instances of type Microsoft.Management.Infrastructure.CimInstance#CIM_Account may be used" } if ($Password.Length -gt 0) { $clearText = (New-Object System.Management.Automation.PSCredential('user',$Password)).GetNetworkCredential().Password if ($CimSession) { $CimAccount = Get-CIMAccount -CimSession $CimSession -UserID $UserID } # TODO: handle case where account has multiple identities $cap = $CimAccount | Get-CimAssociatedInstance -ResultClassName CIM_Identity | Get-CimAssociatedInstance -ResultClassName CIM_AccountManagementService | Get-CimAssociatedInstance -ResultClassName CIM_AccountManagementCapabilities $UserPassword = Convert-Password -Capabilities $cap -ClearText $clearText $CimAccount.UserPassword = $UserPassword $CimAccount | Set-CimInstance Write-Verbose "Command completed successfully." } else { Write-Error "Empty password specified" } } } function Remove-Account { <# .Synopsis Remove account from the target system .Description Remove account from the target system More details of the Simple Identity Management Profile can be found here: http://dmtf.org/sites/default/files/standards/documents/DSP1034_1.0.pdf .Parameter CimAccount Instance of an existing CIM_Account object. See Get-Account help for details. .Parameter CimSession Instance of an existing CimSession object. See New-CimSession help for details. .Parameter UserID UserID of the specific account. .Example PS C:\> # Create new CimSession to out-of-band DASH capable hardware using HTTP and Digest PS C:\> $comp1 = New-CimSession -ComputerName comp1 -Authentication Digest -Credential $cred -port 623 PS C:\> Get-Account -CimSession $comp1 -UserId Steve | Remove-Account #> [CmdletBinding(DefaultParametersetName="CimSession",SupportsShouldProcess=$true)] param ( [Parameter(ParameterSetName="CimAccount",ValueFromPipeLine=$true,Mandatory=$true)] [Microsoft.Management.Infrastructure.CimInstance] $CimAccount, [Parameter(ParameterSetName="CimSession",Mandatory=$true)] [Microsoft.Management.Infrastructure.CimSession] $CimSession, [Parameter(ParameterSetName="CimSession",Mandatory=$true)] [string] $UserID ) process { $ErrorActionPreference = "Stop" if ($CimSession) { $CimAccount = Get-CIMAccount -CimSession $CimSession -UserID $UserID } if (-not $cimAccount.pstypenames.contains("Microsoft.Management.Infrastructure.CimInstance#CIM_Account")) { Write-Error "Only instances of type Microsoft.Management.Infrastructure.CimInstance#CIM_Account may be used" } if ($PSCmdlet.ShouldProcess($CimAccount.GetCimSessionComputerName(),"ClearLog")) { if ($Force -or $PSCmdlet.ShouldContinue("","")) { Remove-CimInstance -InputObject $CimAccount } } } } function Set-Role { <# .Synopsis Add authorized roles to an account on the target system .Description Add authorized roles to an account on the target system More details of the Role Based Authorization Profile can be found here: http://dmtf.org/sites/default/files/standards/documents/DSP1039_1.0.pdf .Parameter CimAccount Instance of an existing CIM_Account object. See Get-Account help for details. .Parameter Role Array of CIM_Role instances. Set Get-Role help for details. .Parameter CimSession Instance of an existing CimSession object. See New-CimSession help for details. .Parameter UserID UserID of the specific account. .Example PS C:\> # Create new CimSession to out-of-band DASH capable hardware using HTTP and Digest PS C:\> $comp1 = New-CimSession -ComputerName comp1 -Authentication Digest -Credential $cred -port 623 PS C:\> $roles = Get-Role -CimSession $comp1 -CommonName CIM:Administrator,CIM:Operator PS C:\> Get-Role -CimSession $comp1 | Set-Role -Role $roles #> [CmdletBinding(DefaultParametersetName="CimSession")] param ( [Parameter(ParameterSetName="CimAccount",Mandatory=$true,ValueFromPipeLine=$true)] [Microsoft.Management.Infrastructure.CimInstance] $CimAccount, [Parameter(Mandatory=$true)] [Microsoft.Management.Infrastructure.CimInstance[]] $Role, [Parameter(ParameterSetName="CimSession",Mandatory=$true)] [Microsoft.Management.Infrastructure.CimSession] $CimSession, [Parameter(ParameterSetName="CimSession",Mandatory=$true)] [string] $UserID ) process { $ErrorActionPreference = "Stop" $returnValueMap = 0,1,2 $returnValues = "Operation completed successfully","Operation unsupported","Failed" if ($CimSession) { $CimAccount = Get-CIMAccount -CimSession $CimSession -UserID $UserID } if (-not $cimAccount.pstypenames.contains("Microsoft.Management.Infrastructure.CimInstance#CIM_Account")) { Write-Error "Only instances of type Microsoft.Management.Infrastructure.CimInstance#CIM_Account may be used" } $roles = @() $Role | ForEach-Object { if (-not $_.pstypenames.contains("Microsoft.Management.Infrastructure.CimInstance#CIM_Role")) { Write-Error "Only instances of type Microsoft.Management.Infrastructure.CimInstance#CIM_Role may be used" } $roles += [ref]$_ } $system = Get-CimSession -InstanceId $CimAccount.GetCimSessionInstanceId() $rbap = Get-RegisteredProfile -CimSession $system -RegisteredName "Role Based Authorization" -RegisteredOrganization DMTF if ($rbap -eq $null) { Write-Warning "$($system.ComputerName) does not support Role Based Authorization Profile" continue } $roleSvc = $rbap | Get-CentralInstance -ResultClassName CIM_RoleBasedAuthorizationService if ($roleSvc -eq $null) { Write-Warning "The remote endpoint did not return CIM_RoleBasedAuthorizationService" return } $identity = $CimAccount | Get-CimAssociatedInstance -ResultClassName CIM_Identity if ($identity.Count -gt 1) { #TODO: handle case where there's multiple identities for an account Write-Error "Module does not currently support setting role where account has multiple identities" } $cap = $roleSvc | Get-CimAssociatedInstance -ResultClassName CIM_RoleBasedManagementCapabilities if ($cap.SupportedMethods -contains 6) { # supports AssignRoles $out = Invoke-CimMethod -InputObject $roleSvc -MethodName AssignRoles -Arguments @{Identity=[ref]$identity;Roles=$roles} if ($out.ReturnValue -eq 0) { Write-Verbose "$(Get-ValueFromMap $returnValues $returnValueMap $out.ReturnValue)" } else { Write-Error "$($system.ComputerName) returned $(Get-ValueFromMap $returnValues $returnValueMap $out.ReturnValue)" } } else { # on systems that don't support AssignRoles, we'll try to assign the same privileges as the specified role # DSP1039 refers to this as one-to-one correspondence Write-Warning "$($system.ComputerName) does not support AssignRoles; assigning privileges instead" $privs = $role | Get-CimAssociatedInstance -ResultClassName CIM_Privilege foreach ($priv in $privs) { $activityQualifiers = $priv.ActivityQualifiers $activities = $priv.Activities $qualifierFormats = $priv.QualifierFormats $userRole = $identity | Get-CimAssociatedInstance -ResultClassName CIM_Role if ($userRole.Count -gt 1) { Write-Error "Module does not currently support setting privileges where account has multiple roles and AssignRoles() method is not implemented on target" } $userPrivilege = $userRole | Get-CimAssociatedInstance -ResultClassName CIM_Privilege if ($userPrivilege.Count -gt 1) { Write-Error "Module does not currently support assign privileges where account role has multiple privilege instances" } $userPrivilege.ActivityQualifiers = $activityQualifiers $userPrivilege.Activities = $activities $userPrivilege.QualifierFormats = $qualifierFormats $userPrivilege | Set-CimInstance } } Write-Verbose "Successfully set role for user $($CimAccount.UserID)" } } function Get-Role { <# .Synopsis Retrieve the roles from the target system .Description Retrieve the roles from the target system More details of the Role Based Authorization Profile can be found here: http://dmtf.org/sites/default/files/standards/documents/DSP1039_1.0.pdf .Parameter CimSession Instance or array of instances of an existing CimSession objects. See New-CimSession help for details. .Parameter CommonName CommonName value of a role to filter against .Example PS C:\> # Create new CimSession to out-of-band DASH capable hardware using HTTP and Digest PS C:\> $comp1 = New-CimSession -ComputerName comp1 -Authentication Digest -Credential $cred -port 623 PS C:\> Get-Role -CimSession $comp1 CommonName ElementName Privileges PSComputerName ---------- ----------- ---------- -------------- CIM:Administrator Administrator Role {Base Desktop and Mobile Read Privilege, Base Desktop and Mobile Write Privilege, Base Desktop and Mob... comp1 CIM:Operator Operator Role {Base Desktop and Mobile Read Privilege, Base Desktop and Mobile Execute Privilege, Physical Asset Rea... comp1 CIM:ReadOnly Read Only Role {Base Desktop and Mobile Read Privilege, Physical Asset Read Privilege, CPU Read Privilege, System Mem... comp1 CIM:Auditor Auditor Role {Record Log Read Privilege, Record Log Audit Privilege} comp1 #> [CmdletBinding(DefaultParametersetName="CimSession")] param ( [Parameter(ParameterSetName="CimSession")] [Microsoft.Management.Infrastructure.CimSession[]] $CimSession = ".", [string[]] $CommonName) process { $ErrorActionPreference = "Stop" foreach ($system in $CimSession) { $rbap = Get-RegisteredProfile -CimSession $system -RegisteredName "Role Based Authorization" -RegisteredOrganization DMTF if ($rbap -eq $null) { Write-Warning "$($system.ComputerName) does not support Role Based Authorization Profile" continue } $roleSvc = $rbap | Get-CentralInstance -ResultClassName CIM_RoleBasedAuthorizationService if ($roleSvc -eq $null) { Write-Warning "The remote endpoint did not return CIM_RoleBasedAuthorizationService" return } foreach ($role in $roleSvc | Get-CimAssociatedInstance -ResultClassName CIM_Role -Association CIM_ServiceAffectsElement) { if ($CommonName.Length -gt 0 -and $CommonName -inotcontains $role.CommonName ) { continue } $priv = $role | Get-CimAssociatedInstance -ResultClassName CIM_Privilege $privs = @() if ($priv -ne $null -and $priv.PrivilegeGranted -eq $true) { if ($priv.ElementName.Length -ne 0) { $privs += $priv.ElementName } else { $privs += $priv.InstanceID } } $role | Add-Member -MemberType NoteProperty -Name Privileges -Value $privs $role.pstypenames.insert(0,"Microsoft.Management.Infrastructure.CimInstance#CIM_Role") $role } } } } function ConvertFrom-HexString { param($HexString) $HexString -split "(..)" | ? { $_ } | % { [Convert]::ToByte($_, 16) } } function ConvertTo-IPMI { param( [byte] $sequenceId = 0, [byte] $messageType, [byte] $messageTag = 0, [byte[]] $data) [byte]$version = 0x06 # ASF [byte]$reserved = 0x00 [byte]$class = 0x06 # ASF [byte[]]$IANA = 0x00,0x00,0x11,0xBE # ASF [byte[]]$RMCPHeader = $version, $reserved, $sequenceId [byte[]] $bytes = $RMCPHeader $bytes += $class $bytes += $IANA $bytes += $messageType $bytes += $messageTag $bytes += $reserved $bytes += $data.Length if ($data.Length -gt 0) { $bytes += $data } $bytes } function Pop-ByteString { param ([ref][string] $byteString, [int] $bytes, [switch] $RemoveDash) $pop = $byteString.Value.SubString(0,3*$bytes) if ($RemoveDash) { $pop = $pop.Replace("-","") } $byteString.Value = $byteString.Value.Remove(0,3*$bytes) $pop } function ConvertFrom-ByteString { param ([string]$byteString) [Convert]::ToInt32($byteString.Replace("-",""),16) } function ConvertFrom-RMCP { param ($byteString) $RMCPAck = "06-00-00-86" $RMCPHeader = "06-00-([0-9A-F]{2})-06-00-00-(11-BE|01-57)-" # handle both ASF and Intel cases in the header if ($byteString -eq $RMCPAck) { Write-Verbose "RMCP Ack received" return } if ($byteString -match $RMCPHeader) { $null = Pop-ByteString ([ref]$byteString) 8 $messageType = Pop-ByteString ([ref]$byteString) 1 switch ($messageType.Replace("-","")) { "40" { Write-Verbose "RMCP Presence Pong Response" $pong = New-Object -TypeName System.Management.Automation.PSObject -Property @{ IPMI=$false;Security=$false;ASF=$false;IANA="Unknown";DASH=$false;HTTP="Unknown"; HTTPS="Unknown"} $pong.PSTypeNames.Insert(0,"RMCP.PresencePong") $messageTag = Pop-ByteString ([ref]$byteString) 1 $reserved = Pop-ByteString ([ref]$byteString) 1 $dataLength = Pop-ByteString ([ref]$byteString) 1 $IANA = Pop-ByteString ([ref]$byteString) 4 switch ($IANA.Replace("-","")) { "000011BE" { $pong.IANA = "ASF" $oemDefined = Pop-ByteString ([ref]$byteString) 4 } "00000157" { $pong.IANA = "Intel" $oemDefined = Pop-ByteString ([ref]$byteString) 4 } "0000113D" { $pong.IANA = "Broadcom" $HTTP = Pop-ByteString ([ref]$byteString) 2 $pong.HTTP = ConvertFrom-ByteString $HTTP $HTTPS = Pop-ByteString ([ref]$byteString) 2 $pong.HTTPS = ConvertFrom-ByteString $HTTPS } Default { Write-Verbose "Unknown IANA: $IANA" $oemDefined = Pop-ByteString ([ref]$byteString) 4 } } [byte]$supportedEntities = [System.Convert]::ToByte((Pop-ByteString ([ref]$byteString) 1 -RemoveDash),16) if ($supportedEntities -band 0x80) { $pong.IPMI = $true } if ($supportedEntities -band 0x01) { $pong.ASF = $true } [byte]$supportedInteractions = [System.Convert]::ToByte((Pop-ByteString ([ref]$byteString) 1 -RemoveDash),16) if ($supportedInteractions -band 0x80) { $pong.Security = $true } if ($supportedInteractions -band 0x20) { $pong.DASH = $true if ($pong.HTTP -eq "Unknown") { $pong.HTTP = 623 } if ($pong.HTTPS -eq "Unknown") { $pong.HTTPS = 664 } } $pong } "41" { Write-Verbose "RMCP Capabilities Response" } "42" { Write-Verbose "RMCP System State Response" } "43" { Write-Verbose "RMCP Open Session Response" } "44" { Write-Verbose "RMCP Close Session Response" } default { Write-Warning "Unknown message type: $messagetype" } } } else { Write-Warning "Unknown response: $byteString" } } function Send-RMCPping { param ([IPAddress] $targetIP, [switch] $ResolveNames = $false) $RMCPport = 623 $bytes = ConvertTo-IPMI -messageType 0x80 -messageTag 0x33 $endPoint = New-Object System.Net.IPEndPoint $targetIP,$RMCPport $udpClient = New-Object System.Net.Sockets.UdpClient $udpClient.Client.SetSocketOption([System.Net.Sockets.SocketOptionLevel]::IP,[System.Net.Sockets.SocketOptionName]::PacketInformation,$true) $null = $udpClient.Send($bytes, $bytes.Length, $endPoint) # method returns number of bytes sent $localEndPoint = New-Object System.Net.IPEndPoint ([IPAddress]::Any),0 Start-Sleep -Milliseconds 200 # give managed node time to formulate response while ($udpClient.Available -gt 0) { try { [byte[]] $receiveBytes = $udpClient.Receive([ref]$localEndPoint) $byteString = [System.BitConverter]::ToString($receiveBytes) Write-Verbose "Bytes Received: $bytestring" $pong = ConvertFrom-RMCP $byteString if ($ResolveNames) { try { # exception if reverse lookup fails because computer is not registered with DNS $computerName = [System.Net.Dns]::GetHostByAddress($localEndPoint.Address) } catch { $computerName = $null } } if ($computerName) { $pong | Add-Member -MemberType NoteProperty -Name ComputerName -Value $computerName.HostName } $pong | Add-Member -MemberType NoteProperty -Name RemoteAddress -Value $localEndPoint.Address.ToString() $pong } catch [System.Net.Sockets.SocketException] { Write-Warning "$targetIP : $($_.Exception.Message)" } } $udpClient.Close() } function Test-RMCPConnection { <# .Synopsis Perform RMCP Ping .Description Send RMCP Ping request to target More information about the data block for RMCP Ping available here: http://www.dmtf.org/sites/default/files/standards/documents/DSP0136.pdf More information on relation of RMCP Ping to DASH available here: http://dmtf.org/sites/default/files/standards/documents/DSP0232_1.1.0.pdf .Parameter CimSession Instance or array of instances of an existing CimSession objects. See New-CimSession help for details. The CimSession is only used to get the target computer name. .Parameter TargetHost Computer name to send the RMCP Ping .Parameter IPAddress IPAddress object to send the RMCP Ping .Parameter Broadcast Send RMCP Ping as broadcast on local subnet .Parameter ResolveNames Use DNS to resolve IP Addresses to Computer Names .Example PS C:\> Test-RMCPConnection -Broadcast IANA DASH HTTP HTTPS IPMI Security RemoteAddress ComputerName ---- ---- ---- ----- ---- ----------- ------------- ------------ Contoso True 623 664 True False 192.168.0.2 comp1 #> [CmdletBinding(DefaultParametersetName="TargetHost")] param ( [Parameter(ParameterSetName="CimSession")] [Microsoft.Management.Infrastructure.CimSession[]] $CimSession = ".", [Parameter(ParameterSetName="TargetHost")] [string] $TargetHost, [Parameter(ParameterSetName="IPAddress")] [IPAddress] $IPAddress, [Parameter(ParameterSetName="Broadcast")] [switch] $Broadcast = $false, [switch] $ResolveNames = $false) process { $ErrorActionPreference = "Stop" $params = @{} if ($ResolveNames) { $params.Add("ResolveNames", $true) } if ($Broadcast) { $ipConfiguration = Get-WmiObject Win32_NetworkAdapterConfiguration | Where-Object IPAddress | Select -First 1 $ipAddress = @($ipConfiguration.IPAddress)[0] $subnetMask = @($ipConfiguration.IPSubnet)[0] [UInt32]$ip = [IPAddress]::Parse($IPAddress).Address [UInt32]$subnet = [IPAddress]::Parse($SubnetMask).Address [UInt32]$broadcast = $ip -band $subnet $BroadcastAddress = New-Object IPAddress ($broadcast -bor -bnot $subnet) Send-RMCPping -target $BroadcastAddress @params } elseif ($TargetHost) { $targetIp = [IPAddress]::Parse([System.Net.Dns]::GetHostByName($TargetHost).AddressList[0]) Send-RMCPping -targetIP $targetIp @params } elseif ($IPAddress) { Send-RMCPping -targetIP $IPAddress @params } else { foreach ($system in $CimSession) { $target = $system.ComputerName $targetIp = [IPAddress]::Parse([System.Net.Dns]::GetHostByName($target).AddressList[0]) $pong = Send-RMCPping -target $targetIp @params $pong } } } } #endregion |