Powershell 管道与参数参数输入?
对于通过管道或参数输入接受值时的区别,我有一个疑问 我这样问是因为:Powershell 管道与参数参数输入?,powershell,powershell-5.1,Powershell,Powershell 5.1,对于通过管道或参数输入接受值时的区别,我有一个疑问 我这样问是因为: 在我的脚本中,通过管道接受值是有效的 使用诸如“-ComputerName”之类的参数参数接受值是可行的 我这样说是因为,它确实从同一个变量获取我的输入,直到有一个变量无法连接,然后停止脚本。这有什么原因吗 以下是我给好奇的人的剧本: Function Set-DWRCVersion { <# NAME Set-DWRCVersion SYNTAX Set-DWRCVersion [[-Co
- 在我的脚本中,通过管道接受值是有效的
- 使用诸如“
”之类的参数参数接受值是可行的-ComputerName
Function Set-DWRCVersion {
<#
NAME
Set-DWRCVersion
SYNTAX
Set-DWRCVersion [[-ComputerName] <string[]>] [<CommonParameters>]
EXAMPLES
Set-DWRCVersion -ComputerName LocalHost,ComputerOne
'LocalHost','ComputerOne' | Set-DWRCVersion
$CritNames | Set-DWRCVersion
$CritNames | Set-DWRCVersion |Export-Csv "$($env:USERPROFILE.Substring(0,20))\Desktop\NewCrit.CSV" -Force -NoTypeInformation
#>
[cmdletbinding()]
Param(
[Parameter(Mandatory=$true,
ValueFromPipeline=$true,
ValueFromPipeLineByPropertyName=$true)]
[ValidateLength(1,15)]
[Alias('Comp','CN','name')]
[string[]]$ComputerName)
Process{
try{
[string]$Path = "C:\Users\Abraham\Desktop\dwrcs" #Dameware File Path (current)
foreach($Computer in $ComputerName){
$PSSession = New-PSSession -ComputerName $Computer -ErrorAction Stop
$TestPath = Invoke-Command -Session $PSSession -ScriptBlock { Test-Path -Path "C:\Windows\dwrcs" }
if($TestPath -eq $false){
Copy-Item -Path $Path -Destination "\\$Computer\C$\Windows" -Recurse -Force }
#Start-Sleep -Seconds 1
$EXEVersion = Invoke-Command -Session $PSSession -ScriptBlock { [System.Diagnostics.FileVersionInfo]::GetVersionInfo("C:\Windows\dwrcs\DWRCS.EXE").FileVersion }
$DLLVersion = Invoke-Command -Session $PSSession -ScriptBlock { [System.Diagnostics.FileVersionInfo]::GetVersionInfo("C:\Windows\dwrcs\DWRCRSS.dll").FileVersion }
if($EXEVersion -notmatch '12.1.2.584'){
[PSCustomObject] @{
"Computer Name" = $Computer
"Status" = "Online"
"DWRC Version" = $EXEVersion
"DWRCRSS DLL" = $DLLVersion
"DWRC Check" = "Not up to date" }
""
Write-Output -InputObject "Version not current"
Write-Output -InputObject "Stopping Service. . ."
Invoke-Command -Session $PSSession -ScriptBlock {
Stop-Service -Name dwmrcs;
Get-Item -Path C:\windows\dwrcs | Rename-Item -NewName "dwrcs.old" }
Remove-Item -Path "\\$Computer\c$\Windows\dwrcs.old" -Recurse -Force -ErrorAction SilentlyContinue
#Start-Sleep 1
Write-Output -InputObject "Copying new files over. . ."
Copy-Item -Path $Path -Destination "\\$Computer\C$\Windows" -Recurse -Force
Write-Output -InputObject "Starting Service. . ."
Invoke-Command -Session $PSSession -ScriptBlock { Start-Service -Name dwmrcs }
}
elseif($EXEVersion -match '12.1.2.584') {
[PSCustomObject] @{
"Computer Name" = $Computer
"Status" = "Online"
"DWRC Version" = $EXEVersion
"DWRCRSS DLL" = $DLLVersion
"Version Check" = "Up to Date" }
}
else { Write-Output -InputObject "Error Occured"
Throw "$($Error[0].Exception.Message)" }
}
} Catch {
[PSCustomObject] @{
"Computer Name" = $Computer
"Status" = "Offline"
"DWRC Version" = $null
"DWRCRSS DLL" = $null
"Version Check" = $null }
} Finally {
if ($PSSession) {
Get-PSSession | Remove-PSSession }
}
}
}
函数集DWRCVersion{
[cmdletbinding()]
Param(
[参数(必需=$true,
ValueFromPipeline=$true,
ValueFromPipeLineByPropertyName=$true)]
[验证长度(1,15)]
[别名('Comp','CN','name')]
[字符串[]]$ComputerName)
过程{
试一试{
[string]$Path=“C:\Users\Abraham\Desktop\dwrcs”#数据软件文件路径(当前)
foreach($ComputerName中的计算机){
$PSSession=新PSSession-ComputerName$Computer-ErrorAction停止
$TestPath=Invoke命令-Session$PSSession-ScriptBlock{TestPath-Path“C:\Windows\dwrcs”}
if($TestPath-eq$false){
复制项目-Path$Path-Destination“\\$Computer\C$\Windows”-Recurse-Force}
#开始睡眠-秒1
$execversion=Invoke命令-Session$PSSession-ScriptBlock{[System.Diagnostics.FileVersionInfo]::GetVersionInfo(“C:\Windows\dwrcs\dwrcs.EXE”).FileVersion}
$DLLVersion=Invoke命令-Session$PSSession-ScriptBlock{[System.Diagnostics.FileVersionInfo]::GetVersionInfo(“C:\Windows\dwrcs\DWRCRSS.dll”).FileVersion}
如果($exevision-不匹配'12.1.2.584'){
[PSCustomObject]@{
“计算机名”=$Computer
“状态”=“联机”
“DWRC版本”=$EXEVersion
“DWRCRSS DLL”=$DLLVersion
“DWRC检查”=“非最新”}
""
写入输出-InputObject“版本非当前”
写入输出-InputObject“正在停止服务…”
调用命令-Session$PSSession-ScriptBlock{
停止服务-名称dwmrcs;
获取项目-路径C:\windows\dwrcs |重命名项目-NewName“dwrcs.old”}
删除项-路径“\\$Computer\c$\Windows\dwrcs.old”-递归-强制-错误操作SilentlyContinue
#开始睡眠1
写入输出-InputObject“通过…复制新文件”
复制项目-路径$Path-目标“\\$Computer\C$\Windows”-递归-强制
写入输出-输入对象“正在启动服务…”
调用命令-Session$PSSession-ScriptBlock{Start Service-Name dwmrcs}
}
elseif($exevision-匹配'12.1.2.584'){
[PSCustomObject]@{
“计算机名”=$Computer
“状态”=“联机”
“DWRC版本”=$EXEVersion
“DWRCRSS DLL”=$DLLVersion
“版本检查”=“最新”}
}
else{写入输出-InputObject“发生错误”
抛出“$($错误[0]。异常。消息)”}
}
}抓住{
[PSCustomObject]@{
“计算机名”=$Computer
“状态”=“脱机”
“DWRC版本”=$null
“DWRCRSS DLL”=$null
“版本检查”=$null}
}最后{
如果($PSSession){
获取PSSession |删除PSSession}
}
}
}
总的来说,这是一个非常简单的脚本,它将为我获得一些远程文件版本。我只是不确定为什么接受管道中的值不会停止脚本,但使用常规参数输入值会停止脚本
Im从csv导入以使用以下内容获取名称:
$Crit = Import-Csv -Path "$($env:USERPROFILE.Substring(0,20))\Desktop\med.csv"
$CritNames = $Crit.'NetBios Name' -replace "AREA51\\",""
<# Names return like so:
COmputerOne
COmputerTwo
COmputerThr
Etc.. #>
$Crit=Import Csv-Path“$($env:USERPROFILE.Substring(0,20))\Desktop\med.Csv”
$CritNames=$Crit.NetBios Name'-替换为“AREA51\\”
当使用管道输入运行它时:$CritNames | Set DWRCVersion
有效,但是,Set DWRCVersion-ComputerName$CritNames
无效;直到它碰到离线计算机,然后停止脚本
我有什么遗漏吗?比我聪明得多的人能教我吗?(:你可以通过移动
foreach
循环中的try
/catch
/finally
语句来解决这个问题:
process {
foreach($Computer in $ComputerName){
try {
# ...
}
catch {
# ...
}
finally {
# ...
}
}
}
为什么这会有不同 当通过
-ComputerName
显式绑定一个值时,进程
块只调用一次,但当您通过管道提供输入时,进程
块会对每个输入项调用一次
您可以使用以下简单的测试函数来观察此行为:
function Test-ProcessInvocation {
param(
[Parameter(Mandatory,ValueFromPipeline)]
[string[]]$ComputerName
)
process {
"Running process block with $($ComputerName.Length) input arguments: [$ComputerName]"
}
}
在两种输入模式下运行此操作将使此行为清晰可见:
PS~>testprocessinvocation-ComputerName 1,2,3
正在使用3个输入参数运行进程块:[1 2 3]
PS~>1,2,3 |测试过程调用
正在使用1个输入参数运行进程块:[1]
正在使用1个输入参数运行进程块:[2]
使用1个输入参数运行进程块
# Single invocation of `process` block with $ComputerName = all input values at once
try {
foreach($Computer in 'Computer1','Computer2'){
}
}
catch {}
finally {}
# `process` block repeats per input item
try {
foreach($Computer in 'Computer1'){
}
}
catch {}
finally {}
try {
foreach($Computer in 'Computer2'){
}
}
catch {}
finally {}