我正在为PowerShell脚本使用参数,但我发现如果第二个参数没有设置,它就会变得垃圾,尽管我可能做错了什么,因为我很难找到带有两个传入参数的示例。我如何验证这两个参数都已设置?
这个脚本是从一个很老的perl脚本调用的,如下所示:
#`"C:\\Program Files\\PowerShell\\7\\pwsh.exe" -NoProfile -noninteractive -ExecutionPolicy bypass -Command "\\\\wserverp01\\kiosksupport\\Retailer_DeviceSN\\MoveSNToSprdsht_1.0.ps1 $service_report_xls"`;
在我的脚本MoveSNToSprdsht_1.0.ps1中:
$out_pth = ""
$outFilePathExcel_pl = ""
$outFilePathExcel_pl = $Args[0]
$out_pth = $Args[1] #this is blob scan output dir that we look for correct date file in
Write-Host "new tab will go to:$($outFilePathExcel_pl)"
Write-Host "Will get files from:$($out_pth)" #this had garbage in it, like terminal output from something I ran yesterday that's unrelated
我在想也许我不应该使用$Args 1,并找到了this example,但它没有说在脚本中使用-arg 1和-arg 2做什么。我现在使用VisualStudioCode运行PowerShell来测试它,所以有可能我从VSC命令行错误地执行它。当我使用旧的perl脚本中粘贴的perl行时,它与第一个参数工作正常,但我现在已经添加了第二个参数。
我在搜索中没有找到如何验证脚本参数是否确实设置。我尝试检查空字符串,但没有成功。某些东西用垃圾填充了Arg 1,因此检查空字符串失败。
更新日期:
那么如果我使用CmdletBinding,这会是一个好的程序结构吗?程序会以正常的方式运行吗?
[cmdletbinding()]
Param ( [Parameter(Mandatory)][string]$outFilePathExcel_pl, [Parameter(Mandatory)][string]$out_pth="\\wserverp01\support\Retailer_SN\OutputSprdsht\")
#and the rest of the program...
Get-ChildItem $out_pth | Foreach-Object {$lastupdatetime=$_.LastWriteTime;$nowtime = get-date; if (($nowtime - $lastupdatetime).totalhours -le 72) {write-host "here2";$excel_File_from = $_.Name;write-host $_.name}}
..
**Update 2:**希望我正确调用powershell脚本,下面,每个评论。
my $resultPS = `"C:\\Program Files\\PowerShell\\7\\pwsh.exe" -NoProfile -noninteractive -ExecutionPolicy bypass -File "\\\\wserverp01\\support\\Retailer_SN\\MoveSNToSprdsht_1.0.ps1" "-outFilePathExcel_pl $service_report_xls" "-out_pth $cvs_blob_scan_dir"`;
调用更新的powershell脚本:
[cmdletbinding()]
param( [Parameter(Mandatory)][string]$outFilePathExcel_pl, [Parameter()][string]$out_pth="\\wserverp01\support\Retailer_SN\OutputSprdsht\")
Start-Transcript -path '\\wserverp01\support\Retailer_SN\Logs\MoveSNToSprdsht.log'
#get file location from parameter so put sn tab there
Write-Host "new tab will go to:$($outFilePathExcel_pl)"
Write-Host "Will get scan files from:$($out_pth)"
#make sure params are valid paths; non-terminating error if invalid
if(Test-Path $outFilePathExcel_pl)
{
Write-Host "path for $outFilePathExcel_pl looks good"
}
else
{
Write-Error "path for $outFilePathExcel_pl invalid"
}
if(Test-Path $out_pth)
{
Write-Host "path for $out_pth looks good"
}
else
{
Write-Error "path for $outFilePathExcel_pl invalid"
}
Get-ChildItem $out_pth | Foreach-Object {$lastupdatetime=$_.LastWriteTime;$nowtime = get-date; if (($nowtime - $lastupdatetime).totalhours -le 72) {write-host "here2";$excel_File_from = $_.Name;write-host $_.name}}
更新3:
由于某种原因,当我从perl使用命名参数并从powershell使用它们时,我得到
Cannot bind argument to parameter 'Path' because it is an empty string.
当我尝试使用变量时。我的语法有问题吗?
Perl:
my $resultPS = `"C:\\Program Files\\PowerShell\\7\\pwsh.exe" -NoProfile -noninteractive -ExecutionPolicy bypass -File "\\\\wserverp01\\support\\Retailer_SN\\MoveSNToSprdsht_1.0.ps1" -outFilePathExcel_pl "$service_report_xls" -out_pth "$retailer_blob_scan_dir"`;
(其中变量是从一个ini文件中设置的,并作为参数传递给脚本,在perl中,powershell调用之前的打印输出看起来不错)
然后在MoveSNToSprdsht_1.0.ps1中:
[cmdletbinding()]
param( [Parameter(Mandatory)][string]$outFilePathExcel_pl, [Parameter()][string]$out_pth="\\wserverp01\support\Retailer_SN\OutputSprdsht\")
Start-Transcript -path '\\wserverp01\support\Retailer_SN\Logs\MoveSNToSprdsht.log'
#get file location from parameter so put sn tab there
Write-Host "new tab will go to:$($outFilePathExcel_pl)" #need to use below instead of $outFilePathExcel############################
Write-Host "Will get blob scan files from:$($out_pth)"
#make sure params are valid paths; non-terminating error if invalid
if(Test-Path $outFilePathExcel_pl)
{
Write-Host "path for $outFilePathExcel_pl looks good"
}
else
{
Write-Error "path for $outFilePathExcel_pl invalid"
}
if(Test-Path $out_pth)
{
Write-Host "path for $out_pth looks good"
}
else
{
Write-Error "path for $out_pth invalid"
}
[System.String] $excel_File_from = ""
############## hours - 72 hours is ok for now so we don't cut it too close for file timestamp for scan..scan run on weekend, use Monday:
Get-ChildItem $out_pth | Foreach-Object {$lastupdatetime=$_.LastWriteTime;$nowtime = get-date; if (($nowtime - $lastupdatetime).totalhours -le 72) {write-host "here2";$excel_File_from = $_.Name;write-host $_.name}}
也许我需要在cmdlet绑定下面使用花括号?如果错误是抱怨使用了空参数,而不是错误的格式。
1条答案
按热度按时间wwwo4jvm1#
$service_report_xls
是一个 Perl 变量,它被字符串扩展。要 * 健壮地 * 传递它,请将它包含在 embedded"..."
中,这需要\\"...\\"
(原文如此):-Command
PowerShell CLI参数,即使这样也会使参数受到不必要的解释。对于执行 * 脚本文件 *(*.ps1
),更好的选择是使用-File
参数,它接受逐字传递的单独参数(有关何时使用-Command
与-File
的指导,请参阅this answer):*.ps1
),请将脚本设置为advanced,这需要正式声明参数并使用[CmdletBinding()]
属性;高级脚本和函数只接受绑定到正式声明的参数的参数;例如:注意:由于声明的参数也可以通过名称绑定(为了概念清晰起见,最好是这样)-例如
...\MoveSNToSprdsht_1.0.ps1 -outFilePathExcel_pl c:\some\file.xlsx
-所以最好使用更具描述性的参数名称。