powershell - 在 Start-Job 中传递 [switch]

标签 powershell

有一个脚本供用户登录,它根据情况依次调用其他脚本。 为了手动单独调用脚本,添加了 [switch]$Silent 参数。问题 - 如何在 Start-Job 中传递此参数?我尝试以不同的方式添加到参数列表中 - 该值始终落入相邻参数中,无论顺序如何。 主脚本示例

Param(
    [string]$location = 'C:\Users',
    [switch]$Silent
)
    Start-Job -FilePath ".\Fonts_Install.ps1" -ArgumentList ($Silent,$location) | Wait-Job

字体_Install.ps1

    Param(
        [switch]$Silent = $false,
        [string]$location = '.'
    )
  $path_fonts = "$env:LOCALAPPDATA\Microsoft\Windows\Fonts"
$Registry = "HKCU:\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Fonts"

function WriteLog {
    Param ([string]$LogString)
    $Stamp = (Get-Date).toString("yyyy/MM/dd HH:mm:ss")
    $LogMessage = "$Stamp $LogString"
    Add-content $LogFile -value $LogMessage
}
$Logfile = "$env:LOCALAPPDATA\Temp\fonts_install.log"

WriteLog "Silent $Silent"
WriteLog "location $location"
Add-Type -AssemblyName System.Windows.Forms
Add-Type -AssemblyName PresentationFramework
Add-Type -AssemblyName System.Drawing
Add-Type -AssemblyName PresentationCore

$SourceFolder = "$location\Fonts_Install"
$WindowsFonts = [System.Drawing.Text.PrivateFontCollection]::new()
$Fonts = Get-ChildItem -Path $SourceFolder -Include *.ttf, *.otf -Recurse -File
ForEach ($Font in $Fonts) {
    $Font_Name = $Font.Name
    $font_fullname = $Font.fullname
    if (Test-Path -PathType Leaf -Path "$path_fonts\$Font_Name") {
        WriteLog "Previously installed $Font_Name"
    }
    else {
        Copy-Item $Font -Destination "$path_fonts" -Force -Confirm:$false -PassThru
        $WindowsFonts.AddFontFile("$font_fullname")
        $ValueFont = "$path_fonts" + "\" + "$Font_Name"
        $Typeface = New-Object -TypeName Windows.Media.GlyphTypeface -ArgumentList "$font_fullname"
        [string]$FamilyFaceNames = $Typeface.FamilyNames.Values + $Typeface.FaceNames.Values
        $RegistryValue = @{
            Path  = $Registry
            Name  = $FamilyFaceNames
            Value = $ValueFont
        }
        if (Test-Path $Registry\$FamilyFaceNames) {
            Remove-ItemProperty -name $FamilyFaceNames -path $Registry
        }
        New-ItemProperty @RegistryValue
        WriteLog "New fonts installed $Font_Name"
    }
}  
    switch ($Silent) {
        $false {
            if ($Error.Count -gt 0) {
                for ($i = 0; $i -le ($Error.Items.Count + 1); $i++) {
                    $errMSG = "$Error"
                }
                [System.Windows.Forms.MessageBox]::Show("$errMSG", "Error", "OK", "Error")
            }
            else {
                [System.Windows.Forms.MessageBox]::Show("ок", "Fonts", "OK", "Asterisk") | out-null
            }
        }
    }

最佳答案

不幸的是,通过 Start-Job 指定传递参数的 -ArgumentList (-Args) 仅限于位置参数,这阻止绑定(bind)[switch ] 参数,其参数根据定义必须命名

作为解决方法,不要使用 -FilePath,而是通过 -ScriptBlock 参数调用脚本。在脚本 block 内部({ ... },命名参数可以像往常一样在脚本调用中使用:

Start-Job -ScriptBlock {

  # Set the current location to the same location as the caller.
  # Note: Only needed in *Windows PowerShell*.
  Set-Location -LiteralPath ($using:PWD).ProviderPath

  .\Fonts_Install.ps1 -Silent:$using:Silent $using:Location

} | Receive-Job -Wait -AutoRemoveJob
  • 请注意使用 $using: 作用域,以便将调用者作用域中的变量值嵌入到将在后台执行的脚本 block 中。

  • 您仍然需要通过名称引用-Silent参数,并且可以通过附加来传达开关是打开还是关闭:$true:$false ,这就是 :$using:Silent 的作用。

  • Windows PowerShell中,后台作业在固定位置(工作目录)执行,即用户的Documents文件夹,因此Set-Location 调用显式使用与调用者相同的位置,以便可以通过相对路径 (.\) 引用脚本文件。在 PowerShell (Core) 7+ 中不再需要这样做,幸运的是,它现在使用与调用者相同的位置。

关于powershell - 在 Start-Job 中传递 [switch],我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/72963472/

相关文章:

powershell - 我是否正确编码此Powershell?因为它没有达到我的预期

powershell - DSC - PowerShell 模块路径中不存在模块

powershell - PowerShell 中的函数范围变量(使用高级方法)?

azure - 在 Azure DevOps Powershell 管道任务中获取自己的服务主体名称

powershell - DSC:模块文件 *ModuleName* 不包含具有所需版本 1.0 的模块

powershell - Powershell 查询的升序和降序

json - 如何使用 ConvertTo-Json 将字符串转换为整数?

powershell - Powershell-错误检查以查找和替换(ForEach对象)

azure - 获取当前订阅 ID

powershell - 无法从远程计算机在 Windows Server 2012 R2 中执行 DSC 文件