PowerShell:什么是';最佳';通过写调试显示变量内容的方法?

PowerShell:什么是';最佳';通过写调试显示变量内容的方法?,powershell,debugging,Powershell,Debugging,如果相应地设置了$DebugPreference,那么显示变量内容的最佳方式是什么?我的印象是,一定有更好/更短/更有效的方法来完成这项工作。。。有什么想法吗 我知道有$MyInvocation.BoundParameters,但是我不知道如何在这个上下文中正确使用它。它返回一个哈希表,该哈希表不由Write Debug显示 Clear-Host $VerbosePreference = "Continue" $DebugPreference = "Continue" $WhatIfPrefer

如果相应地设置了
$DebugPreference
,那么显示变量内容的最佳方式是什么?我的印象是,一定有更好/更短/更有效的方法来完成这项工作。。。有什么想法吗

我知道有
$MyInvocation.BoundParameters
,但是我不知道如何在这个上下文中正确使用它。它返回一个哈希表,该哈希表不由Write Debug显示

Clear-Host
$VerbosePreference = "Continue"
$DebugPreference = "Continue"
$WhatIfPreference = $true

$Global:Config = @{ 
                    SearchBase = "OU=SomeOU,DC=ad,DC=contoso,DC=com" 
                    LogFolder = "C:\Temp"
                    LogFile = $($MyInvocation.MyCommand.Name -replace ".ps1", ".txt")
                    LogPath = "$($Global:Config.LogFolder)\$($Global:Config.LogFile)"
                  }

Write-Debug "$($MyInvocation.MyCommand.Name): SearchBase = $($Global:Config.SearchBase)"
Write-Debug "$($MyInvocation.MyCommand.Name): LogFolder = $($Global:Config.LogFolder)"
Write-Debug "$($MyInvocation.MyCommand.Name): LogFile = $($Global:Config.LogFile)"
Write-Debug "$($MyInvocation.MyCommand.Name): LogPath = $($Global:Config.LogPath)"

Function Move-MyADObjects
{
    [CmdletBinding()]
    Param(
            [Parameter(Mandatory=$true,HelpMessage="define sitecode e.g. xxxxx")]    
            [string]$Sitz
         )

    $TargetPathUsers = "OU=$sitz,OU=Users,$($Global:Config.SearchBase)"
    $TargetPathGroups = "OU=$sitz,OU=Groups,$($Global:Config.SearchBase)"
    $TargetPathServers = "OU=$sitz,OU=Servers,$($Global:Config.SearchBase)"
    $TargetPathClients = "OU=$sitz,OU=Clients,$($Global:Config.SearchBase)"

    Write-Debug "$($MyInvocation.MyCommand.Name): Sitz = $sitz"
    Write-Debug "$($MyInvocation.MyCommand.Name): TargetPathUsers = $TargetPathUsers"
    Write-Debug "$($MyInvocation.MyCommand.Name): TargetPathGroups = $TargetPathUsers"
    Write-Debug "$($MyInvocation.MyCommand.Name): TargetPathServers = $TargetPathUsers"
    Write-Debug "$($MyInvocation.MyCommand.Name): TargetPathClients = $TargetPathUsers"

    Write-Verbose "Working on $sitz" 

    $filter = "*$sitz*"
    Write-Debug "$($MyInvocation.MyCommand.Name): filter = $filter"

    $BaseOU = (Get-ADOrganizationalUnit -Filter {(Name -like $filter)} -SearchBase $Global:Config.SearchBase -SearchScope 1).DistinguishedName

    Write-Debug "$($MyInvocation.MyCommand.Name): BaseOU = $BaseOU"

    $filter = "2*AB*"
    Write-Debug "$($MyInvocation.MyCommand.Name): filter = $filter"

    $UTuser = Get-ADUser -Filter {(Name -like $filter)} -SearchBase $BaseOU
    Write-Debug "$($MyInvocation.MyCommand.Name): UTuser.Count = $($UTuser.Count)"

    Write-Verbose -Message "Moving ABusers from $sitz to target OU"
    $UTuser | Move-ADObject -TargetPath $TargetPathUsers 
}

Move-MyADObjects -Sitz "12345"
编辑

我问这个问题也是因为我显示可变内容的方式不太容易出现编码错误。如果你看我上面的代码,你可能会发现我犯了一个错误。这是因为我不得不反复输入变量名,然后开始复制和粘贴。。。当涉及到真正的调试时,这会导致混乱。所以我想一定有更好(更自动)的方法来实现这一点:-)

但是,对于简单变量(不是哈希表),如果没有 必须重新键入变量的名称。。。下面显示了 变量的内容,但不是它的名称。。。我不想手动操作 键入/重复每个变量

您可以使用
Get Variable
进行此操作。这是一个函数,它将以您想要的方式打印调试输出

function Out-Debug
{
    Param
    (
        [System.Management.Automation.InvocationInfo]$Invocation,

        [Parameter(ValueFromPipeline = $true)]
        [string[]]$Variable,

        [string]$Scope = 1
    )

    Process
    {
        foreach($var in $Variable)
        {
            @(
                "Origin: $($Invocation.MyCommand.Name)",
                "Variable: $var",
                'Value:',
                (Get-Variable -Name $var -Scope $Scope -ValueOnly |
                    Format-Table -AutoSize -Wrap | Out-String)
            ) | Write-Debug
        }
    }
}
用法: 输出:
谢谢这正是我要找的。但是对于简单变量(不是哈希表)如何做到这一点,而不必重新键入变量的名称。。。下面显示的是var的内容,但不是它的名称。。。我不想手动键入/重复每个var
“函数:$($MyInvocation.MyCommand.Name)”,($filter | Format Table-Autosize | Out String)| Write Debug
"Function: $($MyInvocation.MyCommand.Name)", ($Global:Config | Format-Table -Autosize | Out-String).Trim() | Write-Debug
function Out-Debug
{
    Param
    (
        [System.Management.Automation.InvocationInfo]$Invocation,

        [Parameter(ValueFromPipeline = $true)]
        [string[]]$Variable,

        [string]$Scope = 1
    )

    Process
    {
        foreach($var in $Variable)
        {
            @(
                "Origin: $($Invocation.MyCommand.Name)",
                "Variable: $var",
                'Value:',
                (Get-Variable -Name $var -Scope $Scope -ValueOnly |
                    Format-Table -AutoSize -Wrap | Out-String)
            ) | Write-Debug
        }
    }
}
$a = 123
$b = 'qwerty'
$c = @{
    xxx = '111'
    yyy = '222'
}
$Global:d = 'GlobalVar'

Out-Debug -Invocation $MyInvocation -Variable 'a', 'b', 'c'

'a', 'b', 'c' | Out-Debug -Invocation $MyInvocation

Out-Debug -Invocation $MyInvocation -Variable 'd' -Scope 'Global'
DEBUG: Origin: WriteDebug.ps1
DEBUG: Variable: a
DEBUG: Value:
DEBUG: 123

DEBUG: Origin: WriteDebug.ps1
DEBUG: Variable: b
DEBUG: Value:
DEBUG: qwerty

DEBUG: Origin: WriteDebug.ps1
DEBUG: Variable: c
DEBUG: Value:
DEBUG: 
Name Value
---- -----
yyy  222  
xxx  111  



DEBUG: Origin: WriteDebug.ps1
DEBUG: Variable: a
DEBUG: Value:
DEBUG: 123

DEBUG: Origin: WriteDebug.ps1
DEBUG: Variable: b
DEBUG: Value:
DEBUG: qwerty

DEBUG: Origin: WriteDebug.ps1
DEBUG: Variable: c
DEBUG: Value:
DEBUG: 
Name Value
---- -----
yyy  222  
xxx  111  



DEBUG: Origin: WriteDebug.ps1
DEBUG: Variable: d
DEBUG: Value:
DEBUG: GlobalVar