programing

PSCustom Object에서 해시 테이블로

minimums 2023. 4. 8. 08:18
반응형

PSCustom Object에서 해시 테이블로

가장 쉬운 변환 방법은 무엇입니까?PSCustomObject에 대해서Hashtable? 스플랫 연산자, 물결 괄호 및 키 값 쌍으로 보이는 것과 동일하게 표시됩니다.제가 이걸 던지려고 하면[Hashtable]동작되지 않습니다.나도 노력했어.toString()할당된 변수는 문자열이지만 아무것도 표시하지 않습니다. 아이디어가 있습니까?

어렵지 않을 거야.다음과 같은 방법으로 효과를 볼 수 있습니다.

# Create a PSCustomObject (ironically using a hashtable)
$ht1 = @{ A = 'a'; B = 'b'; DateTime = Get-Date }
$theObject = new-object psobject -Property $ht1

# Convert the PSCustomObject back to a hashtable
$ht2 = @{}
$theObject.psobject.properties | Foreach { $ht2[$_.Name] = $_.Value }

Keith는 이미 답변을 드렸습니다. 이것은 원라이너에서도 같은 일을 할 수 있는 또 다른 방법일 뿐입니다.

$psobject.psobject.properties | foreach -begin {$h=@{}} -process {$h."$($_.Name)" = $_.Value} -end {$h}

다음은 중첩된 해시 테이블/어레이에서도 작동하는 버전입니다(DSC ConfigurationData에서 이 작업을 수행하려는 경우 유용합니다).

function ConvertPSObjectToHashtable
{
    param (
        [Parameter(ValueFromPipeline)]
        $InputObject
    )

    process
    {
        if ($null -eq $InputObject) { return $null }

        if ($InputObject -is [System.Collections.IEnumerable] -and $InputObject -isnot [string])
        {
            $collection = @(
                foreach ($object in $InputObject) { ConvertPSObjectToHashtable $object }
            )

            Write-Output -NoEnumerate $collection
        }
        elseif ($InputObject -is [psobject])
        {
            $hash = @{}

            foreach ($property in $InputObject.PSObject.Properties)
            {
                $hash[$property.Name] = (Convert-PSObjectToHashtable $property.Value).PSObject.BaseObject
            }

            $hash
        }
        else
        {
            $InputObject
        }
    }
}

PowerShell 6의 신기능에 의해 실현된 매우 게으른 접근법:

$myhashtable = $mypscustomobject | ConvertTo-Json | ConvertFrom-Json -AsHashTable

이것은 Convert From_Json에 의해 작성된 PSCustom Objects에 대해 기능합니다.

Function ConvertConvertFrom-JsonPSCustomObjectToHash($obj)
{
    $hash = @{}
     $obj | Get-Member -MemberType Properties | SELECT -exp "Name" | % {
                $hash[$_] = ($obj | SELECT -exp $_)
      }
      $hash
}

면책사항:PowerShell에 대해 잘 모르기 때문에 그다지 깔끔하지 않을 수 있습니다.단, (한 레벨에서만) 동작합니다.

내 코드:

function PSCustomObjectConvertToHashtable() {
    param(
        [Parameter(ValueFromPipeline)]
        $object
    )

    if ( $object -eq $null ) { return $null }

    if ( $object -is [psobject] ) {
        $result = @{}
        $items = $object | Get-Member -MemberType NoteProperty
        foreach( $item in $items ) {
            $key = $item.Name
            $value = PSCustomObjectConvertToHashtable -object $object.$key
            $result.Add($key, $value)
        }
        return $result
    } elseif ($object -is [array]) {
        $result = [object[]]::new($object.Count)
        for ($i = 0; $i -lt $object.Count; $i++) {
            $result[$i] = (PSCustomObjectConvertToHashtable -object $object[$i])
        }
        return ,$result
    } else {
        return $object
    }
}

간단한 [PSCustomObject]에서 [Hashtable]로 변환하려면 Keith의 답변이 가장 적합합니다.

그러나 더 많은 옵션이 필요한 경우


function ConvertTo-Hashtable {
    <#
    .Synopsis
        Converts an object to a hashtable
    .DESCRIPTION
        PowerShell v4 seems to have trouble casting some objects to Hashtable.
        This function is a workaround to convert PS Objects to [Hashtable]
    .LINK
        https://github.com/alainQtec/.files/blob/main/src/scripts/Converters/ConvertTo-Hashtable.ps1
    .NOTES
        Base ref: https://community.idera.com/database-tools/powershell/powertips/b/tips/posts/turning-objects-into-hash-tables-2
    #>
    PARAM(
        # The object to convert to a hashtable
        [Parameter(ValueFromPipeline = $true, Mandatory = $true)]
        $InputObject,

        # Forces the values to be strings and converts them by running them through Out-String
        [switch]$AsString,

        # If set, empty properties are Included
        [switch]$AllowNulls,

        # Make each hashtable to have it's own set of properties, otherwise,
        # (default) each InputObject is normalized to the properties on the first object in the pipeline
        [switch]$DontNormalize
    )
    BEGIN {
        $headers = @()
    }
    PROCESS {
        if (!$headers -or $DontNormalize) {
            $headers = $InputObject | Get-Member -type Properties | Select-Object -expand name
        }
        $OutputHash = @{}
        if ($AsString) {
            foreach ($col in $headers) {
                if ($AllowNulls -or ($InputObject.$col -is [bool] -or ($InputObject.$col))) {
                    $OutputHash.$col = $InputObject.$col | Out-String -Width 9999 | ForEach-Object { $_.Trim() }
                }
            }
        } else {
            foreach ($col in $headers) {
                if ($AllowNulls -or ($InputObject.$col -is [bool] -or ($InputObject.$col))) {
                    $OutputHash.$col = $InputObject.$col
                }
            }
        }
    }
    END {
        return $OutputHash
    }
}

이건 과잉 살상일 수도 있지만 도움이 됐으면 좋겠어요

현재 PSCustomObject를 해시 테이블로 변환하는 가장 쉬운 방법은 다음과 같습니다.

$custom_obj | ConvertTo-HashtableFromPsCustomObject    

또는

[hashtable]$custom_obj

반대로 다음 명령을 사용하여 해시 테이블을 PSCustomObject로 변환할 수 있습니다.

[PSCustomObject]$hash_table

다만, 이러한 뛰어난 옵션은, 구버전의 PS에서는 이용할 수 없는 경우가 있습니다.

언급URL : https://stackoverflow.com/questions/3740128/pscustomobject-to-hashtable

반응형