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

Mat*_*tze 2 debugging powershell

$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"
Run Code Online (Sandbox Code Playgroud)

编辑

我也问这个问题,因为我显示变量内容的方式不太容易出现编码错误。如果您查看上面的代码,您可能会发现我犯了一个错误。发生这种情况是因为我必须重复输入 var 名称并开始复制和粘贴...这在实际调试时会导致混乱。所以我想一定有一种更好的(更自动的)方法来做到这一点:-)

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"
Run Code Online (Sandbox Code Playgroud)

bea*_*ker 5

"Function: $($MyInvocation.MyCommand.Name)", ($Global:Config | Format-Table -Autosize | Out-String).Trim() | Write-Debug
Run Code Online (Sandbox Code Playgroud)

但是,对于简单变量(不是哈希表)如何才能做到这一点,而不必重新输入变量的名称...下面显示了 var 的内容,但不显示它的名称...我不想手动输入/重复每个变量

你可以用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
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

用法:

$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'
Run Code Online (Sandbox Code Playgroud)

输出:

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
Run Code Online (Sandbox Code Playgroud)