有一个脚本供用户登录,它根据情况依次调用其他脚本。 为了手动单独调用脚本,添加了 [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/