标签: scriptblock

PowerShell 脚本块内的命令执行顺序

起初我对 PowerShell ScriptBlock 很兴奋,但最近我对它在块内的执行顺序感到困惑。例如:

$test_block = {
  write-host "show 1"
  ps
  write-host "show 2"
  Get-Date
}
Run Code Online (Sandbox Code Playgroud)

调用 $test_block.Invoke() 的输出:

show 1
show 2
<result of command 'ps'>
<result of command 'get-date'>
Run Code Online (Sandbox Code Playgroud)

输出内容的命令会先运行吗?

powershell scriptblock

4
推荐指数
2
解决办法
1785
查看次数

如何使用 $_ 自动变量调用 powershell 脚本块

什么有效 -

假设我有一个scriptblockSelect-Objectcmdlet 一起使用的。

$jobTypeSelector = `
    {
        if ($_.Type -eq "Foo")
        {
            "Bar"
        }
        elseif ($_.Data -match "-Action ([a-zA-Z]+)")
        {
            $_.Type + " [" + $Matches[1] + "]"
        }
        else
        {
            $_.Type
        }
    }

$projectedData = $AllJobs | Select-Object -Property State, @{Name="Type"; Expression=$jobTypeSelector}
Run Code Online (Sandbox Code Playgroud)

这工作正常,并且我得到了预期的结果。

我正在尝试做的事情 -

但是,在稍后的代码中,我想重用scriptblock定义为$jobTypeSelector.

例如,我期望下面的代码采用$fooJob注意它是单个对象)作为下面的参数传递,并用于$_中的自动变量scriptblock并返回相同的结果,因为它在Select-Objectcmdlet 上下文中执行时返回。

$fooType = $jobTypeSelector.Invoke($fooJob)
Run Code Online (Sandbox Code Playgroud)

什么不起作用-

它没有按我的预期工作,我得到了空值。

我已经尝试过的 -

  1. 我检查了一下,属性都设置正确,并不是因为相关属性本身为空或$null.

  2. 我在互联网上查找,似乎很难找到有关该主题的任何相关页面,但我最终找到了一个在稍微不同的上下文中接近解释问题的页面 - …

powershell scriptblock automatic-variable

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

PowerShell ScriptBlock变量范围

我无法理解ScriptBlocks中的范围.我指望某种类似闭包的系统,但我似乎无法让它工作.

我有一个ScriptBlock拿a param并返回另一个ScriptBlock:

$sb1 = {
    Param($Message1);
    Write-Host $Message1;
    {
        Param($Message2);
        Write-Host ($Message1 + " " + $Message2);
    }
}
Run Code Online (Sandbox Code Playgroud)

为了得到内ScriptBlock我可以调用$sb1$sb2 = & $sb1 -Message1 "Message1".这回应Message1所以我们知道它param是受约束的.

现在,我可以调用$sb2& $sb2 -Message2 "Message2".我原以为Message1 Message2,但它只是写作而已Message2.

有没有办法访问$Message1变量?我不能使用本地或脚本变量,因为内部scriptblock的多个实例具有不同的$Message1s.

这是实际shell的实际输出:

PS C:\> $h1 = { Param($Message1); Write-Host $Message1; { Param($Message2); Write-Host ($Message1 + " " + $Message2); } …
Run Code Online (Sandbox Code Playgroud)

powershell closures scope scriptblock

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

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
查看次数

如何将命名函数作为参数传递(scriptblock)

我们来看一下经典的一阶函数示例:

function Get-MyName { "George" }

function Say-Hi([scriptblock]$to) {
  Write-Host ("Hi "+(& $to))
}
Run Code Online (Sandbox Code Playgroud)

这很好用:

Say-Hi { "Fred Flintstone" }
Run Code Online (Sandbox Code Playgroud)

这不是:

Say-Hi Get-MyName
Run Code Online (Sandbox Code Playgroud)

因为Get-MyName被评估,而不是作为值本身传递.如何将Get-MyName作为值传递?

powershell scriptblock

3
推荐指数
1
解决办法
4710
查看次数

Powershell为Func &lt;T&gt;而不是Action &lt;T&gt;创建脚本块

我正在尝试从Powershell使用一个类。此类具有一种称为的方法,该方法Execute()具有两个重载:一个重载了Func<T>,一个重载了Action<T>。我可以调用Action<T>以scriptblock为委托的重载,但是我不知道如何调用以a为代表的重载Func<T>

add-type -TypeDefinition @'
using System;

public class DelegTest
{
    public R Execute<R>(Func<R> method)
    {
        return method();
    }

    public void Execute(Action method)
    {
        Execute(() => { method(); return true; });
    }
}
'@

$t = new-object DelegTest
$t.Execute({ 1 + 1 }) # returns nothing
Run Code Online (Sandbox Code Playgroud)

我怎么称呼需要一个的过载Func<T>?我认为这将需要创建一个具有返回类型的ScriptBlock,但是我不知道该怎么做。Powershell解析器显然不够智能,无法自动执行此操作。

c# powershell overloading scriptblock

3
推荐指数
1
解决办法
1282
查看次数

变量上的++运算符未按ScriptBlock中的预期进行更改

我试图通过在文件中添加基于递增计数器的前缀来重命名文件,例如:

$directory = 'C:\Temp'
[int] $count=71; 

gci $directory | sort -Property LastWriteTime | `
rename-item -newname {"{0}_{1}" -f $count++, $_.Name} -whatif
Run Code Online (Sandbox Code Playgroud)

然而,所有的文件处理是71_$count$count++从不增量和文件名前缀相同?为什么?


在此处输入图片说明

powershell scope pipe scriptblock rename-item-cmdlet

3
推荐指数
1
解决办法
73
查看次数

为什么 pwsh.exe 与 Start-Process 结合使用时不直接接受脚本块?

为什么Start-Process powershell.exe { Read-Host }有效,但Start-Process pwsh.exe { Read-Host }不起作用?

我知道 的-ArgumentList切换Start-Process,但是当涉及转义引号时,它使事情变得更加复杂:

PowerShell 7.0.3 和 7.2.0-preview.3:

Start-Process pwsh.exe -ArgumentList '-Command "& {
    ''Hello World.''
    Read-Host
}"' -Verb RunAs
Run Code Online (Sandbox Code Playgroud)

PowerShell 5.1:

Start-Process powershell.exe { 
    'Hello World.'
    Read-Host
} -Verb RunAs
Run Code Online (Sandbox Code Playgroud)

另一方面,当创建新的 PowerShell 会话(不带Start-Process)时,仍然可以使用脚本块:

pwsh.exe {
    'Hello World.'
    Read-Host
}
Run Code Online (Sandbox Code Playgroud)

我在这里遗漏了一些东西还是有更好/不同的方法允许脚本块与脚本的其余部分并行执行?

powershell start-process scriptblock powershell-core powershell-7.0

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

Powershell启动作业范围

我有一个很长的剧本。我有一个记录功能:

function Log ([string]$Content){
    $Date = Get-Date
    Add-Content -Path $LogPath -Value ("$Date : $Content")
}
Run Code Online (Sandbox Code Playgroud)

在脚本的某些时候,我需要并行运行作业。我有一个计算机名称列表,我需要对每个计算机名称使用 psexec。这应该作为并行运行的作业来完成


        Start-Job -ScriptBlock {
        
        Log "$line Has called"
            $Program_List = gc $USERS_DB_PATH\$line.txt | select -Skip 1
            if (Test-Connection $line -Quiet) {
                    ForEach ($program in $Program_List){
                    Log "$line $program"
                    #"line $line bot is $bot pwd is $pwd"
                    psexec \\"$line" -u bla.local\"$bot" -p $pwd cmd bla
                    
                    }
            }
            else{
                  Log "Cannot Connect to $line"
            }
        
        
        }
        #Remove-Item "$USERS_DB_PATH\$line.txt"


}

Run Code Online (Sandbox Code Playgroud)

我知道这与范围有关,但是如何使这个脚本块看到函数 Log 和所有必要的变量?他们都空了

powershell scope start-job scriptblock

2
推荐指数
1
解决办法
2709
查看次数

ScriptBlock 中的变量 - Powershell

我的 powershell 脚本有一个 GUI。如果 C: 中的文件夹“Temp”不存在 - 创建文件夹并记录条目“Path C:\Temp 不存在 - 创建文件夹”。

这是我的代码的摘录:

$infofolder=$global:dText.AppendText("Path C:\Temp does not exist - create folder`n")

###create C:\Temp if does not exist
       Invoke-Command -Session $session -ScriptBlock {
         $temp= "C:\Temp"
         if (!(Test-Path $temp)) {
                $Using:infofolder
                New-Item -Path $temp -ItemType Directory}
        }
Run Code Online (Sandbox Code Playgroud)

我必须使用在 ScriptBlock 外部定义的变量,因此我使用“$Using”。但变量 $infofolder 只能在脚本块中执行。不幸的是,它之前已经执行过,这没有意义,因为当文件夹存在时也会创建日志记录条目。

我无法使用 $using:global:dText.AppendText("Path C:\Temp does not Exist - createfolder`n")。

谢谢你!!

powershell scriptblock

2
推荐指数
1
解决办法
1718
查看次数