powershell 如何设置verify和use两个参数以避免垃圾

vptzau2j  于 2023-03-30  发布在  Shell
关注(0)|答案(1)|浏览(131)

我正在为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绑定下面使用花括号?如果错误是抱怨使用了空参数,而不是错误的格式。

wwwo4jvm

wwwo4jvm1#

  • 在你的Perl命令行中,$service_report_xls是一个 Perl 变量,它被字符串扩展。要 * 健壮地 * 传递它,请将它包含在 embedded"..."中,这需要\\"...\\"(原文如此):
`"C:\\Program Files\\PowerShell\\7\\pwsh.exe" -NoProfile -noninteractive -ExecutionPolicy bypass -Command "\\\\wserverp01\\kiosksupport\\Retailer_DeviceSN\\MoveSNToSprdsht_1.0.ps1 \\"$service_report_xls\\""`;
  • 然而,由于使用了-CommandPowerShell CLI参数,即使这样也会使参数受到不必要的解释。对于执行 * 脚本文件 *(*.ps1),更好的选择是使用-File参数,它接受逐字传递的单独参数(有关何时使用-Command-File的指导,请参阅this answer):
`"C:\\Program Files\\PowerShell\\7\\pwsh.exe" -NoProfile -NonInteractive -ExecutionPolicy Bypass -File "\\\\wserverp01\\kiosksupport\\Retailer_DeviceSN\\MoveSNToSprdsht_1.0.ps1" "$service_report_xls"`;
  • 为了确保没有意外的参数传递到PowerShell脚本(*.ps1),请将脚本设置为advanced,这需要正式声明参数并使用[CmdletBinding()]属性;高级脚本和函数只接受绑定到正式声明的参数的参数;例如:
[CmdletBinding()] # Make the script an advanced one.
param(
  # Mandatory, 1st positional parameter
  [Parameter(Mandatory)]  # Make sure an argument is always passed.
  [string] $outFilePathExcel_pl,   
  # Optional, 2nd positional parameter with default value.
  [string] $out_pth = '...'
)
# ...

注意:由于声明的参数也可以通过名称绑定(为了概念清晰起见,最好是这样)-例如...\MoveSNToSprdsht_1.0.ps1 -outFilePathExcel_pl c:\some\file.xlsx-所以最好使用更具描述性的参数名称。

相关问题