【问题标题】:Pass parameter to powershell encoded command将参数传递给 powershell 编码命令
【发布时间】:2017-01-08 18:16:55
【问题描述】:

我有一个包含很多行的脚本。 我可以轻松地将此脚本粘贴到脚本块参数中,而无需对其进行编辑(例如,在脚本中的引号前加上反斜杠)。然后我可以对脚本进行编码,以便将其作为编码参数传递给 powershell:

$myscript = {
#paste of simplified script
$calc = 6 + 9
echo $calc
}

# Convert script to a string
$command = $carvingScript.ToString()
# Convert string to base64 encoded command
$bytes = [System.Text.Encoding]::Unicode.GetBytes( $command )
$encodedCommand = [Convert]::ToBase64String( $bytes )

我希望能够在脚本中传递一个参数来进行 base64 转换。像这样:

$parameter = 9
$myscript = {
$calc = 6 + $parameter
echo $calc
}

任何想法如何解决这个问题?我知道 scriptblock 可以包含参数,但是为了解析参数,需要解析整个脚本,而不仅仅是一个参数

【问题讨论】:

  • 你的问题有点不清楚。你能不能把你的脚本块变成一个实际的工作示例,而不是xxx 胡言乱语?另外,这样做的目的是什么? :-)
  • @MathiasR.Jessen 添加了一个示例
  • 假设您的意思是在对原始脚本块进行编码后 传递参数值:不,不幸的是,powershell 不支持 -args 开关与 @ 987654325@

标签: powershell encode scriptblock


【解决方案1】:

如何将变量添加到脚本块的直接答案是:

$parameter = 9

$myscript = @'
$calc = 6 + {0}
echo $calc
'@ -f $parameter

$scriptblock = [scriptblock]::Create($myscript)

基本上将其构建为字符串,并使用[scriptblock]中的create方法进行转换。

但是您可以跳过创建脚本块,因为您将直接将其转换回字符串。

【讨论】:

  • 不需要从字符串创建脚本块,因为无论如何它必须是base64编码的字符串。
  • @AnsgarWiechers 正确。我在发布后不久编辑了我的答案以反映这一点。我留下了那一点,因为它仍然是原始问题的一部分。
  • 感谢您的回答。澄清一下:在我看来,脚本块的优势在于您不需要转义某些字符,例如变量中的美元符号。这就是我最初的问题。
【解决方案2】:

这是一篇旧帖子,但我发现 this 文章对我有用,所以我想与亲爱的社区分享它:)

您可以在脚本块中使用带有强制参数的param 块:

$myscript = {
    param
    (
        [Parameter(Mandatory)]
        [decimal]
        $First,

        [Parameter(Mandatory)]
        [decimal]
        $Second
    )
    [decimal]($First + $Second)
}

$bytes = [System.Text.Encoding]::Unicode.GetBytes($myscript)
$encodedCommand = [Convert]::ToBase64String($bytes)
$encodedCommand | Set-Content 'C:\temp\encodedCommand.txt' -Encoding UTF8

然后在两个powershell.exe调用之间通过管道传递参数:

powershell.exe -noprofile -command "3.3, 2.7" | powershell.exe -encodedcommand DQAKACAAIAAgACAAcABhAHIAYQBtAA0ACgAgACAAIAAgACgADQAKACAAIAAgACAAIAAgACAAIABbAFAAYQByAGEAbQBlAHQAZQByACgATQBhAG4AZABhAHQAbwByAHkAKQBdAA0ACgAgACAAIAAgACAAIAAgACAAWwBkAGUAYwBpAG0AYQBsAF0ADQAKACAAIAAgACAAIAAgACAAIAAkAEYAaQByAHMAdAAsAA0ACgANAAoAIAAgACAAIAAgACAAIAAgAFsAUABhAHIAYQBtAGUAdABlAHIAKABNAGEAbgBkAGEAdABvAHIAeQApAF0ADQAKACAAIAAgACAAIAAgACAAIABbAGQAZQBjAGkAbQBhAGwAXQANAAoAIAAgACAAIAAgACAAIAAgACQAUwBlAGMAbwBuAGQADQAKACAAIAAgACAAKQANAAoAIAAgACAAIABbAGQAZQBjAGkAbQBhAGwAXQAoACQARgBpAHIAcwB0ACAAKwAgACQAUwBlAGMAbwBuAGQAKQANAAoA

这是使用在整体输出中可见的 Powershell 交互式输入模式,因此请注意您是否传递了任何密码或机密:

cmdlet  at command pipeline position 1
Supply values for the following parameters:
First: 3.3
Second: 2.7
6.0

如果您曾经尝试使用列表(数组)参数并将值列表传递给编码命令,那么您需要记住最后一个数组元素必须是空字符串 - 这就是您如何欺骗交互式输入模式来设置列表参数。

您还需要记住不要将列表参数标记为ValueFromPipeline,否则将无法正确使用值。

$command = {
    param
    (
        [Parameter(Mandatory)]
        [string[]]
        $MyList
    )
    $MyList | ForEach-Object { Write-Host $_ }
}

$bytes = [System.Text.Encoding]::Unicode.GetBytes($command)
$encodedCommand = [Convert]::ToBase64String($bytes)
"powershell.exe -noprofile -command `"'test1', 'test2', 'test3', ''`" | powershell.exe -encodedcommand $encodedCommand" | Set-Content 'C:\temp\test.txt' -Encoding UTF8
PS C:\temp> powershell.exe -noprofile -command "'test1', 'test2', 'test3', ''" | powershell.exe -encodedcommand DQAKACAAIAAgACAAcABhAHIAYQBtAA0ACgAgACAAIAAgACgADQAKACAAIAAgACAAIAAgACAAIABbAFAAYQByAGEAbQBlAHQAZQByACgATQBhAG4AZABhAHQAbwByAHkAKQBdAA0ACgAgACAAIAAgACAAIAAgACAAWwBzAHQAcgBpAG4AZwBbAF0AXQANAAoAIAAgACAAIAAgACAAIAAgACQATQB5AEwAaQBzAHQADQAKACAAIAAgACAAKQANAAoAIAAgACAAIAAkAE0AeQBMAGkAcwB0ACAAfAAgAEYAbwByAEUAYQBjAGgALQBPAGIAagBlAGMAdAAgAHsAIABXAHIAaQB0AGUALQBIAG8AcwB0ACAAJABfACAAfQANAAoA


cmdlet  at command pipeline position 1
Supply values for the following parameters:
MyList[0]: test1
MyList[1]: test2
MyList[2]: test3
MyList[3]:
test1
test2
test3

我希望它会在未来对某人有所帮助。和平!

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-05-03
    • 2015-03-03
    • 1970-01-01
    • 2010-11-20
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多