【问题标题】:How can prevent a PowerShell window from closing so I can see the error?如何防止 PowerShell 窗口关闭以便我可以看到错误?
【发布时间】:2021-10-18 18:45:06
【问题描述】:

我正在创建一个本地 PowerShell 模块下载器脚本。模块和脚本保存在网络共享上。使用以下方式调用脚本:

& '\\net\DSFShare\Shared Data\Powershell Modules\Install-MyModuleManager.ps1'

它将脚本复制到标准配置文件模块文件夹,然后从模块文件夹运行 Install.ps1。如果需要,Install.ps1 会提升自己。就在提升的窗口关闭之前,会弹出一个红色错误,但窗口关闭得太快,我看不到错误。我怎样才能找出错误是什么?

下载器脚本使用以下方法调用安装程序:

$installerPath = [IO.Path]::Combine($LocalModulePath, 'Install.ps1')
Write-Host "Installer path: $installerPath"
if (Test-Path $installerPath) {
    Write-Host 'Install.ps1 exists.  Running Install.ps1'
    & $installerPath
}

注意,如果从 PowerShell 填充 $installerPath 并使用 & $installerPath 调用它,我看不到错误。

我检查了应用程序、系统、Windows PowerShell 和安全事件日志。没有任何与此相关的错误。

脚本所做的只是创建一个事件源。如果你想运行它,你可以使用:

Remove-EventLog -Source 'My.Module.Manager'

之后,将其删除。这是脚本:

Write-Host "Installing module..."
$eventSource = 'My.Module.Manager'

try {
    $sourceExists = [System.Diagnostics.EventLog]::SourceExists($eventSource)
} catch [Security.SecurityException] {
    Write-Verbose "Caught 'SecurityException': $_.Exception.Message"
}

if ($sourceExists) {
    Write-Host "...installation complete..."
} else {

    #region ----- Ensure-ProcessIsElevated -----

    if ($Verbose) {
        $VerbosePreference = "Continue"
    }
    if ($Debug) {
        $DebugPreference = "Continue"
    }

    Write-Debug "Command line is ___$($MyInvocation.Line)___"
    Write-Verbose "Entering script body"

    if ($ScriptPath) {
        Set-Location $ScriptPath
        Write-Verbose "Working directory: $pwd"
    }

    If (-Not ([Security.Principal.WindowsPrincipal] [Security.Principal.WindowsIdentity]::GetCurrent()).IsInRole([Security.Principal.WindowsBuiltInRole] "Administrator")) {
        Write-Warning "This script must be run with elevated privileges."
        Write-Warning "Restarting as an elevated process."
        Write-Warning "You will be prompted for authorization."
        Write-Warning "You may click 'No' and re-run manually, if you prefer."

        If ((Get-WmiObject Win32_OperatingSystem | select BuildNumber).BuildNumber -ge 6000) {
            Write-Verbose "This is a UAC-enabled system. Elevating ..."
            $CommandLine = "$($MyInvocation.Line.Replace($MyInvocation.InvocationName, $MyInvocation.MyCommand.Definition)) -ScriptPath $pwd"
            Write-Verbose "CommandLine: $CommandLine"

            Start-Process -FilePath PowerShell.exe -Verb Runas -ArgumentList "$CommandLine"

        } else {
            Write-Verbose "The system does not support UAC: an elevated process cannot be started."
            Write-Warning "This script requires administrative privileges. Please re-run with administrative account."
        }

        Break
    }

    Write-Verbose "The script is now running with elevated privileges."

    #endregion ----- Ensure-ProcessIsElevated -----

    New-EventLog -LogName Application -Source $eventSource

    Write-Host "...installation complete..."
}

我使用的是 PowerShell 4.0。

【问题讨论】:

    标签: powershell


    【解决方案1】:

    您基本上有三个选项来防止 PowerShell 控制台窗口关闭,我描述了in more detail in my blog post

    1. 一次性修复:从 PowerShell 控制台运行脚本,或使用 -NoExit 开关启动 PowerShell 进程。例如,PowerShell -NoExit "C:\SomeFolder\SomeScript.ps1"

    2. 每个脚本修复:在脚本文件末尾添加输入提示。例如,Read-Host -Prompt "Press Enter to exit"

    3. 全局修复:更改您的注册表项以在脚本完成运行后始终保持 PowerShell 控制台窗口打开。这是需要更改的两个注册表项:

      ● 打开方式 → Windows PowerShell
      当您右键单击 .ps1 文件并选择打开方式时

      注册表项: HKEY_CLASSES_ROOT\Applications\powershell.exe\shell\open\command

      默认值:

      "C:\Windows\System32\WindowsPowerShell\v1.0\powershell.exe" "%1"
      

      期望值:

      "C:\Windows\System32\WindowsPowerShell\v1.0\powershell.exe" "& \"%1\""
      

      ● 使用 PowerShell 运行
      当您右键单击 .ps1 文件并选择使用 PowerShell 运行(根据您安装的 Windows 操作系统和更新显示)。

      注册表项: HKEY_CLASSES_ROOT\Microsoft.PowerShellScript.1\Shell\0\Command

      默认值:

      "C:\Windows\System32\WindowsPowerShell\v1.0\powershell.exe" "-Command" "if((Get-ExecutionPolicy ) -ne 'AllSigned') { Set-ExecutionPolicy -Scope Process Bypass }; & '%1'"
      

      期望值:

      "C:\Windows\System32\WindowsPowerShell\v1.0\powershell.exe" -NoExit "-Command" "if((Get-ExecutionPolicy ) -ne 'AllSigned') { Set-ExecutionPolicy -Scope Process Bypass }; & \"%1\""
      

    如果您不想手动修改注册表项,可以从我的博客下载 .reg 文件。

    听起来您可能想使用选项 #2。您甚至可以将整个脚本包装在一个 try 块中,并且仅在发生错误时提示输入,如下所示:

    try
    {
        # Do your script's stuff
    }
    catch
    {
        Write-Error $_.Exception.ToString()
        Read-Host -Prompt "The above error occurred. Press Enter to exit."
    }
    

    【讨论】:

    • 我从您的博客下载了 reg 文件,但它不起作用(在 Windows 10 x64 上):出现错误时 ps1 窗口退出。
    • Re Open With → Windows PowerShell:在保持窗口打开方面,提议的更改看起来像是无操作(尽管它有助于嵌入空格的脚本路径,但更好的解决方法是使用-file).
    【解决方案2】:

    这将使 PowerShell 窗口等待,直到您按下 Enter 键(不是 任何键):

    pause
    

    【讨论】:

    • 我总是最终使用一种解决方法,cmd /c pause,它确实响应任何单个键。
    【解决方案3】:

    也简单易行:

    Start-Sleep 10
    

    【讨论】:

      【解决方案4】:

      最简单的方法是使用-NoExit 参数执行您的特定脚本。

      1.按:打开运行框:

      赢+R

      2.然后在输入提示符中输入:

      PowerShell -NoExit "C:\folder\script.ps1"
      

      然后执行。

      【讨论】:

        【解决方案5】:

        我正在添加注册表脚本,以便在 PowerShell 窗口完成后保持打开状态。

        我是从blog.danskingdom.com那里拿到的

        Windows Registry Editor Version 5.00
        
        [HKEY_CLASSES_ROOT\Applications\powershell.exe\shell\open\command]
        @="\"C:\\Windows\\System32\\WindowsPowerShell\\v1.0\\powershell.exe\" -NoExit \"& \\\"%1\\\"\""
        
        [HKEY_CLASSES_ROOT\Microsoft.PowerShellScript.1\Shell\0\Command]
        @="\"C:\\Windows\\System32\\WindowsPowerShell\\v1.0\\powershell.exe\" -NoExit \"-Command\" \"if((Get-ExecutionPolicy ) -ne 'AllSigned') { Set-ExecutionPolicy -Scope Process Bypass }; & \\\"%1\\\"\""
        

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2020-06-12
          • 2010-12-06
          • 1970-01-01
          • 2010-09-24
          • 1970-01-01
          相关资源
          最近更新 更多