检查PowerShell中是否处于调试模式

检查PowerShell中是否处于调试模式,powershell,debugging,Powershell,Debugging,如果脚本在调试模式下运行,如何签入PowerShell?我目前正在安装PowerShell工具的Visual Studio 2015中进行调试 脚本的一部分使用Send MailMessage发送电子邮件。我想做一些类似于下面的事情 If (Debug) { $messageProperties.To = "$env:username@company.com" } Else { $messageProperties.To = "prodmailbox@company.com" }

如果脚本在调试模式下运行,如何签入PowerShell?我目前正在安装PowerShell工具的Visual Studio 2015中进行调试

脚本的一部分使用Send MailMessage发送电子邮件。我想做一些类似于下面的事情

If (Debug)
{
    $messageProperties.To = "$env:username@company.com"
}
Else
{
    $messageProperties.To = "prodmailbox@company.com"
}
我知道在C#中,我可以做下面这样的事情。我想知道PowerShell是如何处理这一问题的

#if DEBUG
    // Debug code
#endif
在PowerShell中“调试”可能意味着几件事。1) 程序在调试器下运行,2)cmdlet/函数被传递
-Debug
标志或
$DebugPreferences
不是
SilentlyContinue
3)PowerShell跟踪打开,4)Set-PSDebug用于切换跟踪(与#3不同的跟踪类型)

如果您还没有选择其中一个,我建议您选择#2。这很简单(检查
-Debug
是否在
PSBoundVariables
中,或者
$DebugPreferences
的值是否不是
SilentlyContinue
)。它支持
Write-Debug
cmdlet。一般来说,这是PowerShell风格的切换调试输出的方式

如果您确实需要#1,那么正如所解释的,在其核心实现PowerShell调试器将处理两个事件(
debugger.BreakpointUpdated
debugger.DebuggerStop
),因此您需要查看这些事件是否有处理程序

如果您需要#4,您可能需要访问私有数据。唯一以
PSDebug
作为名词的PowerShell 3.0命令是
Set PSDebug
,这意味着没有cmdlet返回
PSDebug
的状态


如果需要#3,则情况类似于#4。没有用于返回跟踪内容信息的cmdlet。

这里有一个函数,可以让您轻松检查;以及一些改变行为的选项

function Test-Debug {
    [CmdletBinding()]
    param (
        [Parameter(Mandatory = $false)]
        [switch]$IgnorePSBoundParameters
        ,
        [Parameter(Mandatory = $false)]
        [switch]$IgnoreDebugPreference
        ,
        [Parameter(Mandatory = $false)]
        [switch]$IgnorePSDebugContext
    )
    process {
        ((-not $IgnoreDebugPreference.IsPresent) -and ($DebugPreference -ne "SilentlyContinue")) -or
        ((-not $IgnorePSBoundParameters.IsPresent) -and $PSBoundParameters.Debug.IsPresent) -or
        ((-not $IgnorePSDebugContext.IsPresent) -and ($PSDebugContext))
    }
}
下面是一些代码,用于演示特定场景中的输出:

#region 'Test Functions'
function Test-InheritExplicit {
    [CmdletBinding()]
    param (
        [Parameter(Mandatory = $false)]
        [switch]$IgnorePSBoundParameters
        ,
        [Parameter(Mandatory = $false)]
        [switch]$IgnoreDebugPreference
        ,
        [Parameter(Mandatory = $false)]
        [switch]$IgnorePSDebugContext
    )
    process {
        #if we weren't splatting all vars over, we could use this trick:
        #[switch]$DebugCopy = $PSBoundParameters.Debug
        #Test-Debug -Debug:$DebugCopy
        Test-Debug @PSBoundParameters
    }
}

function Test-InheritImplicit {
    [CmdletBinding()]
    param (
        [Parameter(Mandatory = $false)]
        [switch]$IgnorePSBoundParameters
        ,
        [Parameter(Mandatory = $false)]
        [switch]$IgnoreDebugPreference
        ,
        [Parameter(Mandatory = $false)]
        [switch]$IgnorePSDebugContext
    )
    process {
        Test-Debug -IgnorePSBoundParameters:$IgnorePSBoundParameters -IgnorePSDebugContext:$IgnorePSDebugContext -IgnoreDebugPreference:$IgnoreDebugPreference
    }
}
#endregion 'Test Functions'

#region 'Test Cases'
[hashtable[]]$testCases = 0..15 | %{
    [hashtable]$new = @{}
    if ($_ -band 1) {$new.Debug = [switch]$true}
    if ($_ -band 2) {$new.IgnorePSBoundParameters = [switch]$true}            
    if ($_ -band 4) {$new.IgnoreDebugPreference = [switch]$true}
    if ($_ -band 8) {$new.IgnorePSDebugContext = [switch]$true}
    $new
}

[int]$t = 0
$testCases | %{
    [hashtable]$testCase = $_
    (New-Object -TypeName PSObject -Property @{
        TestId = ++$t
        Debug = [bool]$_.Debug
        IgnorePSBoundParameters = [bool]$_.IgnorePSBoundParameters
        IgnoreDebugPreference = [bool]$_.IgnoreDebugPreference
        IgnorePSDebugContext = [bool]$_.IgnorePSDebugContext
        TD = (Test-Debug @testCase)
        TIE = (Test-InheritExplicit @testCase)
        TII = (Test-InheritImplicit @testCase)
    })
} | Format-Table  TestId, Debug, IgnorePSBoundParameters, IgnoreDebugPreference, IgnorePSDebugContext, TD, TIE, TII -AutoSize
以下是上面的输出:

TestId Debug IgnorePSBoundParameters IgnoreDebugPreference IgnorePSDebugContext    TD   TIE   TII
------ ----- ----------------------- --------------------- --------------------    --   ---   ---
     1 False                   False                 False                False False False False
     2  True                   False                 False                False  True  True  True
     3 False                    True                 False                False False False False
     4  True                    True                 False                False  True  True  True
     5 False                   False                  True                False False False False
     6  True                   False                  True                False  True  True False
     7 False                    True                  True                False False False False
     8  True                    True                  True                False False False False
     9 False                   False                 False                 True False False False
    10  True                   False                 False                 True  True  True  True
    11 False                    True                 False                 True False False False
    12  True                    True                 False                 True  True  True  True
    13 False                   False                  True                 True False False False
    14  True                   False                  True                 True  True  True False
    15 False                    True                  True                 True False False False
    16  True                    True                  True                 True False False False

具有向后兼容性的示例模板脚本(以及一些注释)

所以,就像我们做检查一样,你可以做如下事情:

[CmdletBinding()]
Param()

# ... some code here creating variables or whatnot ...

if ($DebugPreference -ne "SilentlyContinue") {
  # in debug
  $messageProperties.To = "$env:username@company.com"
} else {
  # not debug
  $messageProperties.To = "prodmailbox@company.com"
}

您能否在PowerShell脚本中为这些选项中的每一个提供一个示例?让我提出建议,更符合SO的精神(作为解决特定编程问题的程序员到程序员资源):使用web搜索查找示例(如有必要),编写一个脚本。如果脚本有问题,请将其添加到OP并更新您的问题。与猜测不同,您是否可以向脚本传递一个开关,告诉它当前状态(即“调试”或“发布”)。您可以将开关的默认值设置为“Debug”
[CmdletBinding()]
Param()

# ... some code here creating variables or whatnot ...

if ($DebugPreference -ne "SilentlyContinue") {
  # in debug
  $messageProperties.To = "$env:username@company.com"
} else {
  # not debug
  $messageProperties.To = "prodmailbox@company.com"
}