如何获得PSCustom对象的长度?

时间:2018-11-01 14:22:32

标签: json powershell

以下内容存储在powershell中

#Maintainer Note: The leftmost parameter must match the registry key name exactly e.g. 'DES 56'
#For more information please check https://support.microsoft.com/en-us/kb/245030
$bannedCiphersJSON = @"
   {
    "RC4 128/128":{
        "IsPermitted":false,
        "AffectedCiphers":[
                        "SSL_RSA_WITH_RC4_128_MD5",
                        "SSL_RSA_WITH_RC4_128_SHA",
                        "TLS_RSA_WITH_RC4_128_MD5",
                        "TLS_RSA_WITH_RC4_128_SHA"
        ]
    },

    "Triple DES 168":{
        "IsPermitted":false,
        "AffectedCiphers":[
                        "SSL_RSA_WITH_3DES_EDE_CBC_SHA",
                        "SSL_DHE_DSS_WITH_3DES_EDE_CBC_SHA" ,
                        "TLS_RSA_WITH_3DES_EDE_CBC_SHA" ,
                        "TLS_DHE_DSS_WITH_3DES_EDE_CBC_SHA"
        ]
    },

    "RC4 56/128":{
        "IsPermitted":false,
        "AffectedCiphers":[
                        "TLS_RSA_EXPORT1024_WITH_RC4_56_SHA"
        ]
    },

    "DES 56":{
        "IsPermitted":false,
        "AffectedCiphers":[
                        "SSL_RSA_WITH_DES_CBC_SHA"
        ]
    },

    "RC4 40/128":{
        "IsPermitted":false,
        "AffectedCiphers":[
                        "SSL_RSA_EXPORT_WITH_RC4_40_MD5",
                        "TLS_RSA_EXPORT_WITH_RC4_40_MD5"
        ]
    },

    "RC2 40/128":{
        "IsPermitted":false,
        "AffectedCiphers":[
                        "SSL_RSA_EXPORT_WITH_RC2_CBC_40_MD5",
                        "TLS_RSA_EXPORT_WITH_RC2_CBC_40_MD5"
        ]
    },

    "MD5":{
        "IsPermitted":false,
        "AffectedCiphers":[
                        "SSL_RSA_EXPORT_WITH_RC4_40_MD5",
                        "SSL_RSA_WITH_RC4_128_MD5",
                        "SSL_RSA_EXPORT_WITH_RC2_CBC_40_MD5",
                        "TLS_RSA_EXPORT_WITH_RC4_40_MD5",
                        "TLS_RSA_WITH_RC4_128_MD5",
                        "TLS_RSA_EXPORT_WITH_RC2_CBC_40_MD5"
        ]
    },

    "SHA":{
        "IsPermitted":false,
        "AffectedCiphers":[
                        "SSL_RSA_WITH_RC4_128_SHA",
                        "SSL_RSA_WITH_DES_CBC_SHA",
                        "SSL_RSA_WITH_3DES_EDE_CBC_SHA",
                        "SSL_RSA_EXPORT1024_WITH_DES_CBC_SHA",
                        "SSL_RSA_EXPORT1024_WITH_RC4_56_SHA",
                        "TLS_RSA_WITH_RC4_128_SHA",
                        "TLS_RSA_WITH_DES_CBC_SHA",
                        "TLS_RSA_WITH_3DES_EDE_CBC_SHA",
                        "TLS_RSA_EXPORT1024_WITH_DES_CBC_SHA",
                        "TLS_RSA_EXPORT1024_WITH_RC4_56_SHA"
        ]
    }
}
"@

$bannedCiphers =$bannedCiphersJSON  | ConvertFrom-Json

function Get-TLSProtocol{ 

    For ($i=0; $i -lt $bannedCiphers.Count; $i++)
    {

      write-output  $i 
    }
}

Get-TLSProtocol

当我对对象运行Get-Member时,每个对象似乎都是一个“注释属性”。因此,我认为数组定义不正确。 (我的目标是获取可用于检查注册表的对象列表。

PS C:\users\golden> $bannedCiphers | get-member


   TypeName: System.Management.Automation.PSCustomObject

Name           MemberType   Definition
----           ----------   ----------
Equals         Method       bool Equals(System.Object obj)
GetHashCode    Method       int GetHashCode()
GetType        Method       type GetType()
ToString       Method       string ToString()
DES 56         NoteProperty System.Management.Automation.PSCustomObject DES 56=@{IsPermitted=False; AffectedCiphers=...
MD5            NoteProperty System.Management.Automation.PSCustomObject MD5=@{IsPermitted=False; AffectedCiphers=Sys...
RC2 40/128     NoteProperty System.Management.Automation.PSCustomObject RC2 40/128=@{IsPermitted=False; AffectedCiph...
RC4 128/128    NoteProperty System.Management.Automation.PSCustomObject RC4 128/128=@{IsPermitted=False; AffectedCip...
RC4 40/128     NoteProperty System.Management.Automation.PSCustomObject RC4 40/128=@{IsPermitted=False; AffectedCiph...
RC4 56/128     NoteProperty System.Management.Automation.PSCustomObject RC4 56/128=@{IsPermitted=False; AffectedCiph...
SHA            NoteProperty System.Management.Automation.PSCustomObject SHA=@{IsPermitted=False; AffectedCiphers=Sys...
Triple DES 168 NoteProperty System.Management.Automation.PSCustomObject Triple DES 168=@{IsPermitted=False; Affected...

在powershell中定义对象以便我可以遍历最顶层的正确方法是什么?

5 个答案:

答案 0 :(得分:4)

您有一个PSCustomObject,而不是数组。该对象具有一些埋在属性中的数组。 [咧嘴]这是获取列表和计数的一种方法...

$AffectedCiphers = foreach ($PropName in $Test.PSObject.Properties.Name)
    {
    $Test.$PropName.AffectedCiphers
    }

'There are {0} ciphers in the Banned Ciphers list.' -f $AffectedCiphers.Count

输出:

  

“禁止的密码”列表中有30种密码。

以上所述:

  • 调用所有powershell对象的隐藏.PSObject属性
  • 获取父对象中的常规属性列表
  • 遍历列表,获取.AffectedCiphers属性值(在这种情况下为值数组)
  • 将它们保存到$AffectedCiphers
  • 获取$AffectedCiphers中的项目数

希望有帮助,

答案 1 :(得分:1)

这可能不是最佳解决方案,但确实演示了如何迭代json内容。您无需了解Length / Count即可实现这一目标。

Foreach($member in ($bannedCiphers | Get-Member -MemberType NoteProperty | Select-Object -ExpandProperty Name)){

    Write-Host "Name: $member"
    Write-Host "IsPermitted: $($bannedCiphers.$member.IsPermitted)"

    Write-Host "Ciphers:$($bannedCiphers.$member.AffectedCiphers.Count)"
    Foreach ($cipher in ($bannedCiphers.$member.AffectedCiphers)){
        Write-Host " - $cipher"
    }
    Write-Host "`n"
}

编辑:添加了$($bannedCiphers.$member.AffectedCiphers.Count)

答案 2 :(得分:0)

我认为唯一的方法是遍历CustomObject ist以获取所有成员,然后使用forEach遍历成员。 我的解决方案与gms0ulmans解决方案几乎相同,但是要短一些。

($bannedCiphers | Get-Member -MemberType NoteProperty).ForEach({
    $member = $_.Name
    $value = $bannedCiphers.($_.Name)
    Write-Host "Member: $member"
    Write-Host "Is Permitted: " + $value.IsPermitted
    Write-Host "Affected Ciphers + " ($value.AffectedCiphers -join ",")
})

答案 3 :(得分:0)

只需根据您的评论添加到其他答案中即可。.如果您可以控制数据源(例如在脚本中对JSON blob进行了硬编码),则只需定义一个对象即可,而不必依赖转换:

$obj = @{
    'RC4 128/128' = @{
        'IsPermitted'     = $false
        'AffectedCiphers' = @(
            'SSL_RSA_WITH_RC4_128_MD5'
            'SSL_RSA_WITH_RC4_128_SHA'
            'TLS_RSA_WITH_RC4_128_MD5'
            'TLS_RSA_WITH_RC4_128_SHA'
        )
    }

    <# ... #>
}

现在您可以本地访问对象(在本例中为hashtable):

$obj.Keys

等等。

答案 4 :(得分:0)

完整的代码,供您参考:

#Maintainer Note: The leftmost parameter must match the registry key name exactly e.g. 'DES 56'
#For more information please check https://support.microsoft.com/en-us/kb/245030
$bannedCiphersJSON = @"
[
  {
    "Name": "RC4 128/128",
    "IsPermitted": false,
    "AffectedCiphers": [
      "SSL_RSA_WITH_RC4_128_MD5",
      "SSL_RSA_WITH_RC4_128_SHA",
      "TLS_RSA_WITH_RC4_128_MD5",
      "TLS_RSA_WITH_RC4_128_SHA"
    ]
  },
  {
    "Name": "Triple DES 168",
    "IsPermitted": false,
    "AffectedCiphers": [
      "SSL_RSA_WITH_3DES_EDE_CBC_SHA",
      "SSL_DHE_DSS_WITH_3DES_EDE_CBC_SHA",
      "TLS_RSA_WITH_3DES_EDE_CBC_SHA",
      "TLS_DHE_DSS_WITH_3DES_EDE_CBC_SHA"
    ]
  },
  {
    "Name": "RC4 56/128",
    "IsPermitted": false,
    "AffectedCiphers": [
      "TLS_RSA_EXPORT1024_WITH_RC4_56_SHA"
    ]
  },
  {
    "Name": "DES 56",
    "IsPermitted": false,
    "AffectedCiphers": [
      "SSL_RSA_WITH_DES_CBC_SHA"
    ]
  },
  {
    "Name": "RC4 40/128",
    "IsPermitted": false,
    "AffectedCiphers": [
      "SSL_RSA_EXPORT_WITH_RC4_40_MD5",
      "TLS_RSA_EXPORT_WITH_RC4_40_MD5"
    ]
  },
  {
    "Name": "RC2 40/128",
    "IsPermitted": false,
    "AffectedCiphers": [
      "SSL_RSA_EXPORT_WITH_RC2_CBC_40_MD5",
      "TLS_RSA_EXPORT_WITH_RC2_CBC_40_MD5"
    ]
  },
  {
    "Name": "MD5",
    "IsPermitted": false,
    "AffectedCiphers": [
      "SSL_RSA_EXPORT_WITH_RC4_40_MD5",
      "SSL_RSA_WITH_RC4_128_MD5",
      "SSL_RSA_EXPORT_WITH_RC2_CBC_40_MD5",
      "TLS_RSA_EXPORT_WITH_RC4_40_MD5",
      "TLS_RSA_WITH_RC4_128_MD5",
      "TLS_RSA_EXPORT_WITH_RC2_CBC_40_MD5"
    ]
  },
  {
    "Name": "SHA",
    "IsPermitted": false,
    "AffectedCiphers": [
      "SSL_RSA_WITH_RC4_128_SHA",
      "SSL_RSA_WITH_DES_CBC_SHA",
      "SSL_RSA_WITH_3DES_EDE_CBC_SHA",
      "SSL_RSA_EXPORT1024_WITH_DES_CBC_SHA",
      "SSL_RSA_EXPORT1024_WITH_RC4_56_SHA",
      "TLS_RSA_WITH_RC4_128_SHA",
      "TLS_RSA_WITH_DES_CBC_SHA",
      "TLS_RSA_WITH_3DES_EDE_CBC_SHA",
      "TLS_RSA_EXPORT1024_WITH_DES_CBC_SHA",
      "TLS_RSA_EXPORT1024_WITH_RC4_56_SHA"
    ]
  }
]
"@

$bannedCiphers = $bannedCiphersJSON  | ConvertFrom-Json

function Get-TLSCipher{ 

    $TLSProtocolCollection = @()
    $regIsEnabledResult
    $regIsEnabledResultFriendly
    $cipherError 

    For ($i=0; $i -lt $bannedCiphers.Name.Count; $i++)
    {
            $TLSProtocolResult = New-Object System.Object
            $cipherError = ""

            $clientPath = "HKLM:\SYSTEM\CurrentControlSet\Control\SecurityProviders\SCHANNEL\Ciphers\" + $bannedCiphers.Name[$i]   
            $canProceedWithKey = Test-Path -Path $clientPath 
            if ($canProceedWithKey)
            {
                $regIsEnabledResult = (Get-ItemProperty -path $clientPath).Enabled
                if ($regIsEnabledResult -eq 0xffffffff -or $regIsEnabledResult -eq 0) {
                   $regIsEnabledResultFriendly = "false"

                   if($bannedCiphers.IsPermitted[$i] -eq "true")
                   {
                       $cipherError = "Should be enabled"
                   }
                }
                else
                {
                   $regIsEnabledResultFriendly = "true"

                   if($bannedCiphers.IsPermitted[$i] -eq "false")
                   {
                       $cipherError = "Should be disabled"
                   }
                }
            }
            else
            {
                $regIsEnabledResultFriendly = "OS Default"
                $cipherError = "Unknown Status" #todo - consider adding a dictionary to determine this outcome
            }

            $TLSProtocolResult | Add-Member -MemberType NoteProperty -Name CipherShortName -Value $bannedCiphers.Name[$i]  
            $TLSProtocolResult | Add-Member -MemberType NoteProperty -Name IsEnabled -Value $regIsEnabledResultFriendly
            $TLSProtocolResult | Add-Member -MemberType NoteProperty -Name Errors -Value $cipherError

            $TLSProtocolCollection += $TLSProtocolResult 
    }

    #Alert if there are cipher configurations on the machine that aren't considered in the script
    $canProceedWithKey2 = Test-Path -Path "HKLM:\SYSTEM\CurrentControlSet\Control\SecurityProviders\SCHANNEL\Ciphers"  
    if ($canProceedWithKey2)
    {
        $unexpectedKeys = Get-ChildItem "HKLM:\SYSTEM\CurrentControlSet\Control\SecurityProviders\SCHANNEL\Ciphers"
        foreach ($crossCheck in $unexpectedKeys)
        {
            if (!$TLSProtocolCollection.CipherShortName.Contains($crossCheck.PSChildName))
            {
                $TLSProtocolResult = New-Object System.Object

                $TLSProtocolResult | Add-Member -MemberType NoteProperty -Name CipherShortName -Value $crossCheck.PSChildName 
                $TLSProtocolResult | Add-Member -MemberType NoteProperty -Name IsEnabled -Value $crossCheck.Enabled
                $TLSProtocolResult | Add-Member -MemberType NoteProperty -Name Errors -Value "Unexpected registry key. Update the 'bannedCiphersJSON' for this registry value"

                $TLSProtocolCollection += $TLSProtocolResult 
            }
        }
    }

    $TLSProtocolCollection
}

Get-TLSCipher