245 lines
10 KiB
PowerShell
245 lines
10 KiB
PowerShell
function Get-MachineInventory {
|
|
<#
|
|
.SYNOPSIS
|
|
Returns an Object that Represents the State of a Machine
|
|
|
|
.DESCRIPTION
|
|
Executes multiple collectors which describe the state of a machine. Can execute on an array of
|
|
machine names or PSSessions and allows for an optional filter to be included. May be returned as a PSObject, JSON, or XML
|
|
|
|
.PARAMETER TargetComputerNames
|
|
[string[]] One or more remote computers to profile
|
|
|
|
.PARAMETER PsSessions
|
|
[PSSession[]] One or more PSSessions to Use
|
|
|
|
.PARAMETER Filter
|
|
[string[]] A filter which limits the number of profilers to execute
|
|
|
|
.PARAMETER JsonOutput
|
|
[switch] Specifies to return the result as JSON
|
|
|
|
.PARAMETER XmlOutput
|
|
[switch] Specifies to return the result as XML
|
|
|
|
.INPUTS
|
|
None
|
|
|
|
.OUTPUTS
|
|
An object with details about the machine state. May be a PSObject (default), JSON, or XML depending on arguments
|
|
|
|
.EXAMPLE
|
|
Get-MachineInventory
|
|
|
|
[Get-MachineInventory] : Collecting data from 1 target(s)
|
|
WARNING: [ALKA01VMA167] : Function Get-AppSettingsInventory Took 00:00:02.2702503 to Execute
|
|
[Get-MachineInventory] : Received 1 result(s)
|
|
[Get-MachineInventory] : Adding Results for ALKA01VMA167
|
|
[Get-MachineInventory] : Inventory Collection Complete After 00:00:07.9261976
|
|
|
|
Name Value
|
|
---- -----
|
|
ALKA01VMA167 {OS, Version, Architecture, GenerationTime...}
|
|
|
|
|
|
.EXAMPLE
|
|
Get-MachineInventory -Filter Uptime, FileSystem
|
|
|
|
[Get-MachineInventory] : Collecting data from 1 target(s)
|
|
[Get-MachineInventory] : Received 1 result(s)
|
|
[Get-MachineInventory] : Adding Results for ALK-DELL1323
|
|
|
|
Name Value
|
|
---- -----
|
|
ALK-DELL1323 {OS, Version, Architecture, GenerationTime...}
|
|
|
|
.EXAMPLE
|
|
Get-MachineInventory -Filter Uptime -MachineNames @("localhost", "ALKA01VMA163.fh.local")
|
|
|
|
[Get-MachineInventory] : Collecting data from 2 target(s)
|
|
[Get-MachineInventory] : Received 2 result(s)
|
|
[Get-MachineInventory] : Adding Results for ALKA01VMA163
|
|
[Get-MachineInventory] : Adding Results for ALK-DELL1323
|
|
|
|
Name Value
|
|
---- -----
|
|
ALKA01VMA163 {OS, Version, Architecture, GenerationTime...}
|
|
ALK-DELL1323 {OS, Version, Architecture, GenerationTime...}
|
|
#>
|
|
[CmdletBinding(DefaultParameterSetName = 'FilterOnlyParameterSet')]
|
|
[OutputType([string], ParameterSetName=("MachineNameParameterJson","SessionParameterJson","FilterParameterSetJson"))]
|
|
[OutputType([System.Xml.XmlDocument], ParameterSetName=("MachineNameParameterXml","SessionParameterXml","FilterParameterSetXml"))]
|
|
[OutputType([System.Collections.Specialized.OrderedDictionary], ParameterSetName=("MachineNameParameterSet","SessionParameterSet"))]
|
|
param(
|
|
|
|
[Parameter(ParameterSetName = 'MachineNameParameterSet', Mandatory = $true)]
|
|
[Parameter(ParameterSetName = 'MachineNameParameterJson', Mandatory = $true)]
|
|
[Parameter(ParameterSetName = 'MachineNameParameterXml', Mandatory = $true)]
|
|
[Alias("ComputerNames", "Servers", "MachineNames")]
|
|
[string[]]$TargetComputerNames,
|
|
|
|
[Parameter(ParameterSetName='SessionParameterSet', Mandatory=$true)]
|
|
[Parameter(ParameterSetName='SessionParameterJson', Mandatory=$true)]
|
|
[Parameter(ParameterSetName='SessionParameterXml', Mandatory=$true)]
|
|
[Alias("Sessions")]
|
|
[System.Management.Automation.Runspaces.PSSession[]]$PsSessions,
|
|
|
|
[Parameter(ParameterSetName = 'MachineNameParameterJson', Mandatory = $true)]
|
|
[Parameter(ParameterSetName = 'SessionParameterJson', Mandatory = $true)]
|
|
[Parameter(ParameterSetName = 'FilterParameterSetJson', Mandatory = $false)]
|
|
[Alias("JsonOutput")]
|
|
[switch]$AsJson,
|
|
|
|
[Parameter(ParameterSetName = 'MachineNameParameterXml', Mandatory = $true)]
|
|
[Parameter(ParameterSetName = 'SessionParameterXml', Mandatory = $true)]
|
|
[Parameter(ParameterSetName = 'FilterParameterSetXml', Mandatory = $false)]
|
|
[Alias("XMLOutput")]
|
|
[switch]$AsXML
|
|
)
|
|
DynamicParam {
|
|
# Define the Paramater Attributes
|
|
$ParameterName = "Filter"
|
|
$RuntimeParameterDictionary = New-Object System.Management.Automation.RuntimeDefinedParameterDictionary
|
|
$AttributeCollection = New-Object System.Collections.ObjectModel.Collection[System.Attribute]
|
|
|
|
$ParameterAttribute = New-Object System.Management.Automation.ParameterAttribute
|
|
$ParameterAttribute.Mandatory = $false
|
|
$ParameterAttribute.ParameterSetName = "__AllParameterSets"
|
|
$AttributeCollection.Add($ParameterAttribute)
|
|
|
|
# Generate and add the ValidateSet
|
|
$arrSet = $inventoryFilterSetOptions | ForEach-Object { $_.FilterName }
|
|
$ValidateSetAttribute = New-Object System.Management.Automation.ValidateSetAttribute($arrSet)
|
|
$AttributeCollection.Add($ValidateSetAttribute)
|
|
|
|
# Create the dynamic parameter
|
|
$RuntimeParameter = New-Object System.Management.Automation.RuntimeDefinedParameter($ParameterName, [string[]], $AttributeCollection)
|
|
$RuntimeParameterDictionary.Add($ParameterName, $RuntimeParameter)
|
|
return $RuntimeParameterDictionary
|
|
}
|
|
|
|
begin {
|
|
# Bind the Filter dynamic parameter to a variable
|
|
$logLead = Get-LogLeadName
|
|
Write-Host "$logLead : Executing using ParameterSet: [$($PSCmdlet.ParameterSetName)]"
|
|
|
|
$filterCollection = $PsBoundParameters[$ParameterName]
|
|
Write-Host "$logLead : Executing with filters: [$filterCollection]"
|
|
|
|
# We'll Silently Continue for Any Provider Errors -- They Get Added to the Results
|
|
$originalErrorActionPreference = $ErrorActionPreference
|
|
$ErrorActionPreference = "SilentlyContinue"
|
|
|
|
$functionStopWatch = [System.Diagnostics.StopWatch]::StartNew()
|
|
|
|
$inventoryResult = New-Object System.Collections.Specialized.OrderedDictionary
|
|
}
|
|
|
|
process {
|
|
try {
|
|
$clearSessions = $true
|
|
if ($null -eq $PsSessions -or $PsSessions.Count -eq 0) {
|
|
$sessions = @()
|
|
foreach ($target in $TargetComputerNames) {
|
|
Write-Host "$logLead : Creating Session for $target"
|
|
$sessions += New-PSSession -ComputerName $target -ErrorVariable err -ErrorAction SilentlyContinue
|
|
|
|
if($err.Count -gt 0) {
|
|
Write-Warning "$logLead : New-PSSession encountered an error : $err"
|
|
}
|
|
}
|
|
} else {
|
|
$clearSessions = $false
|
|
$sessions = $PsSessions
|
|
}
|
|
|
|
$scriptBlock = {
|
|
|
|
$logLead = "[$env:COMPUTERNAME]"
|
|
$ErrorActionPreference = "Continue"
|
|
|
|
$machineData = New-Object System.Collections.Specialized.OrderedDictionary
|
|
$uniqueSections = $Using:inventoryFilterSetOptions | ForEach-Object { $_.SectionVariable } | Sort-Object | Select-Object -Unique
|
|
|
|
$VerbosePreference=$Using:VerbosePreference;
|
|
|
|
foreach ($section in $uniqueSections) {
|
|
Write-Verbose "$logLead : Creating Variable for $section Data"
|
|
New-Variable -Name $section -Value (New-Object System.Collections.Specialized.OrderedDictionary)
|
|
}
|
|
|
|
# Always include Platform Inventory as Top Level Properties
|
|
$machineData += Get-PlatformInventory
|
|
|
|
# Use the entire filter set if no filter was set as a parameter
|
|
[array]$filteredInventories = Test-IsNull $Using:filterCollection ($Using:inventoryFilterSetOptions | ForEach-Object { $_.FilterName }) -Strict
|
|
Write-Verbose "$logLead : Using Final Inventory Filter: [$filteredInventories]"
|
|
|
|
foreach ($inventory in ($filteredInventories | Sort-Object)) {
|
|
|
|
$matchingFilter = $Using:inventoryFilterSetOptions | Where-Object {$_.FilterName -eq $inventory}
|
|
|
|
$masterProviderStopWatch = [System.Diagnostics.StopWatch]::StartNew()
|
|
|
|
Write-Host "$logLead : Executing FunctionName [$($matchingFilter.FunctionName)]"
|
|
$sb = [ScriptBlock]::Create($matchingFilter.FunctionName)
|
|
((Get-Variable -Name $matchingFilter.SectionVariable).Value) += (Invoke-Command $sb)
|
|
|
|
$masterProviderStopWatch.Stop()
|
|
|
|
if ($masterProviderStopWatch.ElapsedMilliseconds -ge 1000) {
|
|
|
|
Write-Warning "$logLead : Function $($matchingFilter.FunctionName) Took $($masterProviderStopWatch.Elapsed) to Execute"
|
|
}
|
|
}
|
|
|
|
foreach ($uniqueSection in $uniqueSections) {
|
|
$section = (Get-Variable -Name $uniqueSection -ValueOnly)
|
|
if ($section.Count -gt 0) {
|
|
|
|
Write-Verbose "$logLead : Adding $uniqueSection Section to Results"
|
|
$machineData.Add("$uniqueSection", $section)
|
|
}
|
|
}
|
|
|
|
return $machineData
|
|
}
|
|
|
|
Write-Host "$logLead : Collecting data from $($sessions.Count) target(s)"
|
|
[array]$results = Invoke-Command -ScriptBlock $scriptBlock -Session $sessions
|
|
|
|
Write-Host "$logLead : Received $($results.Count) result(s)"
|
|
|
|
# Add Result Sets
|
|
foreach ($result in $results) {
|
|
Write-Host "$logLead : Adding Results for $($result.Hostname)"
|
|
$inventoryResult.Add($result.Hostname, $result)
|
|
}
|
|
} finally {
|
|
Write-Host "$logLead : Setting ErrorActionPreference to $originalErrorActionPreference"
|
|
$ErrorActionPreference = $originalErrorActionPreference
|
|
|
|
if ($clearSessions) {
|
|
if ($sessions.Count -gt 0) {
|
|
Write-Host "$logLead : Cleaning Up PSSessions"
|
|
Remove-PSSession $sessions;
|
|
} else {
|
|
Write-Error "$logLead : WinRM cannot connect to any computers in the input list."
|
|
}
|
|
}
|
|
}
|
|
|
|
$functionStopWatch.Stop()
|
|
Write-Host "$logLead : Inventory Collection Complete After $($functionStopWatch.Elapsed)"
|
|
|
|
if ($AsJson) {
|
|
return ($inventoryResult | ConvertTo-Json -Depth 8)
|
|
}
|
|
|
|
if ($AsXml) {
|
|
return ($inventoryResult | ConvertTo-Xml -Depth 8 -As Document)
|
|
}
|
|
|
|
return $inventoryResult
|
|
}
|
|
} |