Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/powershell/13.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/variables/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Powershell 在ScriptBlock中对变量使用Invoke命令_Powershell_Variables_Parameters_Invoke Command_Scriptblock - Fatal编程技术网

Powershell 在ScriptBlock中对变量使用Invoke命令

Powershell 在ScriptBlock中对变量使用Invoke命令,powershell,variables,parameters,invoke-command,scriptblock,Powershell,Variables,Parameters,Invoke Command,Scriptblock,PowerShell新手,通过使用帮助信息编写随机脚本进行学习。我尝试了以下3种方法来正确地将变量放入ScriptBlock中(同时列出了太多的小变体),并将列出的错误消息包装在**中: do { try { [ValidateRange(1,7)][int]$days = Read-Host "Let's pull up some Warning event logs. How many days back would you like to go back? (1-7)"

PowerShell新手,通过使用帮助信息编写随机脚本进行学习。我尝试了以下3种方法来正确地将变量放入ScriptBlock中(同时列出了太多的小变体),并将列出的错误消息包装在**中:

do
{
try {
[ValidateRange(1,7)][int]$days = Read-Host "Let's pull up some Warning event logs. How many days back would you like to go back? (1-7)"
} catch {}
} until ($?)

do
{
try {
[ValidateSet('desktop','documents',IgnoreCase)]$location = Read-Host "Would you like me to save the log on your Desktop or in your Documents?"
} catch {}
} until ($?)
$filename = Read-Host "What would you like to name the file?"
$DaysAgo = [datetime]::Now.AddDays(-$days)
Invoke-Command -AsJob -Jobname JobEventLog -ScriptBlock {Get-EventLog -logname system | Where-Object EntryType -eq Warning | where TimeGenerated -ge $DaysAgo | Out-File $HOME\$location\$filename.txt}
调用命令:无法使用指定的命名参数解析参数集。


调用命令:无法使用指定的命名参数解析参数集。


Invoke命令:无法验证参数“ScriptBlock”上的参数。参数为空。请为参数提供有效值,然后再次尝试运行该命令。


我只是想让用户输入他们想查看事件日志的时间、保存位置以及名称。到目前为止,我已经能够以自己的方式完成所有的工作,直到我点击Invoke命令行,但仍然无法完成。与参数样式相比,我更喜欢1和2的单行样式,但是在花费了太多时间使用help_Invoke-Command-full和Google搜索之后,我放弃了我确定的语法上的一个简单错误。

您可以在scriptblock中使用
$args
,请参见示例:

$DaysAgo = [datetime]::Now.AddDays(-$days)
Invoke-Command -AsJob -Jobname JobEventLog -ScriptBlock {
Get-EventLog -logname system | Where-Object EntryType -eq Warning | 
where TimeGenerated -ge $args[0] | 
Out-File $HOME\$location\$filename.txt
} -ArgumentList $DaysAgo

Invoke命令的末尾添加参数,如示例中所示,并对第一个参数使用
$args[0]
,对第二个参数使用$args[1],依此类推……

这对我很有效。计算机是本地主机,作为测试,在提升的提示符下运行,您仍然需要该提示符作为系统日志。第三级是警告。如果是同一台计算机,则根本不需要invoke命令

$location = 'foo'
$filename = 'myfile'
$date = get-date
$daysago = $date.adddays(-1) 
invoke-command localhost { param($daysago, $location, $filename)
  get-winevent @{logname = 'system'; level = 3; starttime = $daysago} |
  out-file $home\$location\$filename.txt } -args $daysago,$location,$filename
要使用的
-AsJob
开关,您必须远程执行代码
,例如使用
-ComputerName
-Session
参数定位不同的计算机

如果没有此类参数,您的命令将在本地运行,但由于上述语法限制,它将失败

如果要在本地运行作业,请直接使用:

$job = Start-Job -Name JobEventLog -ScriptBlock {
    Get-EventLog -logname system | 
      Where-Object EntryType -eq Warning | 
        Where-Object TimeGenerated -ge $using:DaysAgo | 
          Out-File $HOME\$using:location\$using:filename.txt
  }
注意:由于后台脚本块引用调用者作用域中的变量,因此必须使用:
作用域通过
$引用它们(正如您在上次基于
调用命令的尝试中所做的那样)。此要求也适用于远程执行的脚本块,例如通过
调用命令-ComputerName
-请参阅以获取背景信息。另一种方法是通过
-ArgumentList
-Args
)参数将参数传递给脚本块,尽管
$using:
方法通常更简单

Start Job
返回作业信息对象(),您可以使用各种
*-Job
cmdlet,尤其是和-查看概念帮助主题,使用该对象监视后台作业的进度并从中获取输出

一般来说,使用
Invoke命令执行本地代码,虽然技术上受支持,但很少需要

对于命令或脚本块的直接、同步调用(不是作为作业),请使用
&
,(对于单个命令不需要,只要命令名没有被引用或通过变量指定),或者对于直接在调用方作用域中执行,
,(
{…}
)。

您有两个选项。由于您仅在本地计算机上运行此命令,因此可以使用
启动作业
而不是
调用命令

话虽如此,你遇到的问题是双重的。首先,如果正在运行
Invoke命令
cmdlet,则需要指定ComputerName参数。即使它是一个可选参数,您也需要使用它来告诉Powershell您正在使用哪个参数集,否则它会变得混乱

其次,需要将参数传递到scriptblock中。这是因为Start Job和Invoke命令是PSRemoting的一部分,实际上会在指定的计算机上查找环境变量,而不是在脚本中声明的变量

以下是对我有效的方法:

Invoke-Command -ComputerName $(hostname) -AsJob -JobName "TestJob" -ScriptBlock { Get-EventLog -logname system | Where-Object EntryType -eq Warning | Where-Object -property TimeGenerated -ge $args[0] | Out-File "$HOME\$($args[1])\$($args[2]).txt" } -ArgumentList $DaysAgo, $location, $filename
如果您希望从网络上的其他设备获取此信息,则
Invoke命令
选项功能强大

以下是
开始作业
版本:

Start-Job -Name "TestJob2" -ScriptBlock { Get-EventLog -logname system | Where-Object EntryType -eq Warning | Where-Object -property TimeGenerated -ge $args[0] | Out-File "$HOME\$($args[1])\$($args[2]).txt" } -ArgumentList $DaysAgo, $location, $filename

$DaysAgo=[datetime]::Now.AddDays(-$days)Invoke命令-AsJob-Jobname JobEventLog-ScriptBlock{Get EventLog-logname system | Where Object EntryType-eq Warning | Where TimeGenerated-ge$args[0]| Out File$args[1]\$args[2]\$args[3].txt}-ArgumentList$DaysAgo、$HOME、$location、$filename这仍然会给出相同的错误,我是否没有正确列出单独的args/argumentlist?我想我有时是在正确的轨道上,但在错误的时间有正确的答案,例如在开始时尝试启动作业时缺少args,然后在错误地尝试调用命令时有args。谢谢不用担心,我觉得我是在用正确的答案调情,因为我有正确的想法,只是没有正确地组合这些部分,例如使用$using:但直到我停止尝试启动作业并开始尝试调用命令之后,我才发现这一点。我开始使用Start Job/Invoke命令的唯一原因是,我想在继续使用脚本之前完成一个命令输出,因为我想在完成输出后再编写一个主机(如果我需要在长时间运行的脚本中使用这个想法,我会向前考虑)。谢谢你的帮助!我的荣幸,跳跳虎。不确定您是否遇到了这种情况,但请注意,存在一个微妙的输出同步问题,甚至会影响同步命令:请参阅
Invoke-Command -ComputerName $(hostname) -AsJob -JobName "TestJob" -ScriptBlock { Get-EventLog -logname system | Where-Object EntryType -eq Warning | Where-Object -property TimeGenerated -ge $args[0] | Out-File "$HOME\$($args[1])\$($args[2]).txt" } -ArgumentList $DaysAgo, $location, $filename
Start-Job -Name "TestJob2" -ScriptBlock { Get-EventLog -logname system | Where-Object EntryType -eq Warning | Where-Object -property TimeGenerated -ge $args[0] | Out-File "$HOME\$($args[1])\$($args[2]).txt" } -ArgumentList $DaysAgo, $location, $filename