I'm started a query for our infrastructure to see how SNMP Service is configured on the servers. I managed to find a function that would extract just the relevant keys and values (without the PS* properties) from the 3 Registry paths :
- HKLM:\SYSTEM\CurrentControlSet\services\SNMP\Parameters\RFC1156Agent
- HKLM:\SYSTEM\CurrentControlSet\Services\SNMP\Parameters\ValidCommunities
- HKLM:\SYSTEM\CurrentControlSet\Services\SNMP\Parameters\PermittedManagers
Edit 1: I've copied the wrong Function initially. Also added the missing part where the function is called. I hope this clears out the confusion
Function Get-HashedProperty {
[CmdletBinding()]
Param(
[Parameter(Mandatory=$True)]
[ValidateScript({Test-Path $_})]
[String]$RegPath,
[Parameter(Mandatory=$False)]
[ValidateSet("Json","HashTable")]
[String]$As
)
$Hash = @{}
Get-ItemProperty "$RegPath" |
Get-Member -MemberType NoteProperty |
Where-Object {$_.Name -notlike "PS*"} | Foreach {
$_ | Select-Object -ExpandProperty Name | Foreach {
$Value = Get-ItemProperty "$RegPath" -Name "$_"
$Hash.Add("$_","$($Value."$_")")
}
}
If($As -eq "Json"){
$Hash = $Hash | ConvertTo-Json
}
Return $Hash
}
$mypaths = @("HKLM:\SYSTEM\CurrentControlSet\Services\SNMP\Parameters\ValidCommunities","HKLM:\SYSTEM\CurrentControlSet\services\SNMP\Parameters\RFC1156Agent","HKLM:\SYSTEM\CurrentControlSet\Services\SNMP\Parameters\PermittedManagers")
$all = $mypaths | foreach { Get-HashedProperty $_ }
The output of $all
variable is below.
Name | Value |
---|---|
BO@CA_w3Ad | 8 |
BO@CA_r3Ad | 4 |
sysLocation | |
sysContact | |
sysServices | 76 |
one | hp-sim-ap |
three | hp-sim-ap |
1 | localhost |
two | hp-sim-ap |
What i'm struggling is to get this values in a separate hashtable or PSObject where i have to add also the ServerName and the InstallState of the SNMP Service. Whatever i do i still get the registry values as array.
Server | SNMP-Service | Col1 | Col2 |
---|---|---|---|
MyTestServer | Installed | {BO@CA_w3Ad, BO@CA_r3Ad, sysLocation, sysContact...} | {8, 4, , ...} |
I tried in few different ways, but i assume my lack of knowledge makes it hard to understand where i'm doing wrong.
For example
$a = @()
$item = New-Object PSObject -Property @{
Server = $ENV:ComputerName
'SNMP-Service' = (Get-WindowsFeature -Name SNMP-Service | Select InstallState).InstallState
Col1 = @($All.Keys)
Col2 = @($all.Values)
}
$a = $item
$a
}
Expected output should be
Server | SNMP-Service | Name | Value |
---|---|---|---|
MyTestServer | Installed | BO@CA_w3Ad | 8 |
MyTestServer | Installed | BO@CA_r3Ad | 4 |
MyTestServer | Installed | sysLocation | |
MyTestServer | Installed | sysContact | |
MyTestServer | Installed | sysServices | 76 |
MyTestServer | Installed | one | hp-sim-ap |
MyTestServer | Installed | three | hp-sim-ap |
MyTestServer | Installed | 1 | localhost |
MyTestServer | Installed | two | hp-sim-ap |
Would highly appreciate a bit of help here :(
CodePudding user response:
I suggest refactoring your approach:
Use the intrinsic
psobject
property to reflect on the properties of theGet-ItemProperty
output objects, which allows you to eliminate thePS
-prefixed properties.Then, for each remaining property, construct a
[pscustomobject]
instance withName
andValue
properties, which you can supplement with the desiredServer
andSNMP-Service
properties.
$mypaths |
Get-ItemProperty |
ForEach-Object {
foreach ($prop in $_.psobject.Properties.Where({ $_.Name -notlike 'PS*'})) {
# Construct and output an object with the desired properties.
[pscustomobject] @{
Server = $ENV:ComputerName
# Note: Better to move this call out of the loop and use a cached value.
'SNMP-Service' = (Get-WindowsOptionalFeature -Name SNMP-Service).InstallState
Name = $prop.Name
Value = $prop.Value
}
}
}
This outputs a stream of objects with the desired structure and values, which you can capture in an array by simple assignment ($a = ...
).