标签: scriptblock

将参数传递给PowerShell中的scriptblock

我猜你不能这样做:

  $servicePath = $args[0]

  if(Test-Path -path $servicePath) <-- does not throw in here

  $block = {

        write-host $servicePath -foreground "magenta"

        if((Test-Path -path $servicePath)) { <-- throws here.

              dowork 
        }
  }
Run Code Online (Sandbox Code Playgroud)

那么如何将我的变量传递给scriptblock $ block?

powershell scriptblock

40
推荐指数
4
解决办法
7万
查看次数

Powershell - 如何在Start-Job的scriptblock中预先评估变量

我想在Powershell中使用后台作业.

如何在ScriptBlock定义时评估变量?

$v1 = "123"
$v2 = "asdf"

$sb = {
    Write-Host "Values are: $v1, $v2"
}

$job = Start-Job -ScriptBlock $sb

$job | Wait-Job | Receive-Job

$job | Remove-Job
Run Code Online (Sandbox Code Playgroud)

我得到$ v1和$ v2的空值.如何让它们在(通过)脚本块中进行评估,从而对后台作业进行评估?

powershell jobs background start-job scriptblock

17
推荐指数
2
解决办法
2万
查看次数

PowerShell使用Start-Process在脚本块中执行函数会使用双引号进行奇怪的操作

我有一个编辑注册表的PowerShell脚本,所以它需要以管理员身份运行.为此,我从运行的PowerShell脚本启动一个新的PowerShell进程,并使用带有函数的脚本块传递部分注册表键路径.当我在该函数中使用双引号时,PowerShell会尝试将它们解释为命令,而不是字符串.如果我使用单引号,那么一切正常.

我创建了一个简单的样本PowerShell脚本来重现问题.这是片段:

$ScriptBlock = {
    function Test
    {
        $status = "This is a string"
        Write-Output $status
    }
}
Start-Process -FilePath PowerShell -ArgumentList "-NoExit -NoProfile -ExecutionPolicy Bypass -Command & {$ScriptBlock Test}"
Run Code Online (Sandbox Code Playgroud)

因此,在新的PowerShell流程中,它将首先在脚本块中定义代码,然后调用Test方法,并产生以下错误:

这:术语"This"不被识别为cmdlet,函数,脚本文件或可操作程序的名称.检查名称的拼写,或者如果包含路径,请验证路径是否正确,然后重试.

所以它试图将字符串视为一个commad,就好像我刚刚This is a string在我的脚本中的新行上键入它一样.

如果我换行

$status = "This is a string"
Run Code Online (Sandbox Code Playgroud)

$status = 'This is a string'
Run Code Online (Sandbox Code Playgroud)

该脚本按预期工作,只是输出字符串This is a string.

我注意到的另一个奇怪的问题是,如果我不使用变量,只需使用:

Write-Output "This is a string"
Run Code Online (Sandbox Code Playgroud)

然后它在一个单独的行上输出每个单词,如下所示:

这个

一个

但如果我使用这样的单引号:

Write-Output 'This is a string'
Run Code Online (Sandbox Code Playgroud)

然后它按预期在一行输出整个句子.

有人知道为什么PowerShell在这些情况下会表现得很奇怪吗?

回答

正如TessellatingHeckler所提到的,解决方案是用双引号,单引号包装任何双引号,或者你可以使用括号.

所以在我的例子中,你会改变: …

string powershell function start-process scriptblock

6
推荐指数
1
解决办法
8702
查看次数

支持词法范围的ScriptBlock参数(例如Where-Object)

考虑以下任意函数和测试用例:

Function Foo-MyBar {
    Param(
        [Parameter(Mandatory=$false)]
        [ScriptBlock] $Filter
    )

    if (!$Filter) { 
        $Filter = { $true } 
    }

    #$Filter = $Filter.GetNewClosure()

    Get-ChildItem "$env:SYSTEMROOT" | Where-Object $Filter   
}

##################################

$private:pattern = 'T*'

Get-Help Foo-MyBar -Detailed

Write-Host "`n`nUnfiltered..."
Foo-MyBar

Write-Host "`n`nTest 1:. Piped through Where-Object..."
Foo-MyBar | Where-Object { $_.Name -ilike $private:pattern  }

Write-Host "`n`nTest 2:. Supplied a naiive -Filter parameter"
Foo-MyBar -Filter { $_.Name -ilike $private:pattern }
Run Code Online (Sandbox Code Playgroud)

在测试1中,我们Foo-MyBar通过Where-Object过滤器管道结果,该过滤器将返回的对象与包含在私有范围变量中的模式进行比较$private:pattern.在这种情况下,这将正确返回C:\中以字母开头的所有文件/文件夹T.

在测试2中,我们直接将相同的过滤脚本作为参数传递给Foo-MyBar.但是,Foo-MyBar到运行过滤器时, …

powershell closures scope function scriptblock

6
推荐指数
2
解决办法
176
查看次数

Powershell启动过程,用于启动Powershell会话并传递局部变量

有没有一种方法可以使用Powershell Start-Process cmdlet启动新的Powershell会话并传递带有局部变量的脚本块(其中一次将是数组)?

例:

$Array = @(1,2,3,4)

$String = "This is string number"

$Scriptblock = {$Array | ForEach-Object {Write-Host $String $_}}

Start-Process Powershell -ArgumentList "$Scriptblock"
Run Code Online (Sandbox Code Playgroud)

谢谢。

powershell start-process scriptblock

5
推荐指数
1
解决办法
1万
查看次数

脚本块中的 Powershell 扩展变量

我正在尝试按照这篇文章扩展脚本块中的变量

我的代码尝试这样做:

$exe = "setup.exe"

invoke-command -ComputerName $j -Credential $credentials -ScriptBlock {cmd /c 'C:\share\[scriptblock]::Create($exe)'}
Run Code Online (Sandbox Code Playgroud)

如何修复错误:

The filename, directory name, or volume label syntax is incorrect.
    + CategoryInfo          : NotSpecified: (The filename, d...x is incorrect.:String) [], RemoteException
    + FullyQualifiedErrorId : NativeCommandError
    + PSComputerName        : remote_computer
Run Code Online (Sandbox Code Playgroud)

variables powershell scriptblock

5
推荐指数
2
解决办法
5788
查看次数

为什么$ PSItem在使用基于括号的-Filter参数时没有按预期运行?

我正在帮助用户解决这个问题,链接到我的答案:Powershell脚本只使用电子邮件地址从.csv添加用户到A/D组?

最初我按如下方式编写脚本,使用基于括号的过滤器,Get-AdUser如下所示:

Import-CSV "C:\users\Balbahagw\desktop\test1.csv" | 
  Foreach-Object {

    # Here, $_.EmailAddress refused to resolve
    $aduser = Get-ADUser -Filter { EmailAddress -eq $_.EmailAddress }

    if( $aduser ) {
      Write-Output "Adding user $($aduser.SamAccountName) to groupname"
      Add-ADGroupMember -Identity groupname -Members $aduser
    } else {
      Write-Warning "Could not find user in AD with email address $($_.EmailAddress)"
    }
  }
Run Code Online (Sandbox Code Playgroud)

但是,$_.EmailAddress未能填充值.但是,将Get-ADUser过滤器更改为基于字符串的过滤器按预期工作:

$aduser = Get-ADUser -Filter "EmailAddress -eq '$($_.EmailAddress)'"

我遇到的奇怪是什么,为什么?是因为当我使用括号时,它被视为一个新范围而$PSItem不会遵循?

powershell filter active-directory scriptblock

5
推荐指数
1
解决办法
141
查看次数

在脚本块 powershell 中调用函数

我有在 Octopus 中注册 Tentacle 的代码,我想在 Scriptblock 中调用一个名为 RunCommand 的函数。当我尝试在脚本块内调用它时,它总是失败。我正在从 csv 文件读取数据,但无法弄清楚如何调用 Scritblock 内的函数。任何人都知道这是如何做到的。正如您从代码中看到的,我正在调用 RunCommand 函数,但它一直失败。我已经使用了以下函数:call,但这也不起作用。请帮忙。

function RunCommand{
Param(
  [string]$myCommand,
  [string]$myArgs
  )

$process = Start-Process -FilePath $myCommand -ArgumentList $myArgs -Wait -PassThru
if ($process.ExitCode -eq 0){
    Write-Host "$myCommand successful"
} else {
    Write-Host "$myCommand failed"
}  
return $process.ExitCode
Run Code Online (Sandbox Code Playgroud)

函数部署触手{

#Read data from a csv file
$csv = Import-Csv -Path "C:\Users\adm_qvl6\Documents\RegisterTentacle.csv"

$csv | ForEach-Object {
    $ServerName = $($_.ServerName)
    $WorkerName = $($_.WorkerName)
    $Port = $($_.Port)  
    $Space = $($_.Space)    
    $Pool = $($_.Pool)
    $TentacleSource = $($_.TentacleSource) …
Run Code Online (Sandbox Code Playgroud)

powershell scriptblock

5
推荐指数
1
解决办法
5929
查看次数

使用Set-Item和GetNewClosure创建Powershell函数

我正在尝试构建一个函数,它本身可以通过Set-Item命令创建函数,我将新函数的scriptblock传递给Set-Item的-Value参数.我遇到一个问题,在脚本块上使用GetNewClosure似乎不起作用,我只是不知道我做错了什么.

在下面的代码中,首先我手动创建一个函数(testFunc)按预期工作,在函数创建后将$ x设置为2将不会导致函数返回2; 相反,它返回1,因为这是创建函数时$ x的值.但是当我尝试通过make-function函数执行相同操作时,行为会发生变化.

我敢肯定我忽视了一些小事.

> $x = 1
> $block = {$x}.GetNewClosure()
> Set-Item function:global:testFunc -Value $block
> testFunc
1 

> $x = 2
> testFunc
1 # still 1 because of GetNewClosure - this is expected behavior

> $x = 1
> function make-function { $block2 = {$x}.GetNewClosure()
       Set-Item function:global:testFunc2 -Value $block2
  }
> make-function
> testFunc2
1 

> $x = 2
> testFunc2
2 # Why is it not returning 1 in this case? 
Run Code Online (Sandbox Code Playgroud)

powershell scriptblock

4
推荐指数
1
解决办法
495
查看次数

Powershell:在脚本块中使用变量来引用 $_ 的属性

$var =@(  @{id="1"; name="abc"; age="1"; },
          @{id="2"; name="def"; age="2"; } );
$properties = @("ID","Name","Age") ;
$format = @();
foreach ($p  in $properties)
{
    $format += @{label=$p ; Expression = {$_.$p}} #$_.$p is not working!
}
$var |% { [PSCustomObject]$_  } | ft $format
Run Code Online (Sandbox Code Playgroud)

在上面的例子中,我想通过一个变量名访问每个对象的属性。但它不能按预期工作。所以就我而言,如何制作

Expression = {$_.$p}
Run Code Online (Sandbox Code Playgroud)

在职的?

powershell closures scriptblock

4
推荐指数
1
解决办法
4009
查看次数