使用带引号的参数从命令行执行Powershell脚本

时间:2013-05-23 05:24:39

标签: powershell command-line escaping build-automation

我正在自动构建旧版MS Access应用程序,并且在其中一个步骤中,我正在尝试创建Access可执行文件(.ADE)。我提出了以下代码,它存储在一个文件(PSLibrary.ps1)中:

Add-Type -AssemblyName Microsoft.Office.Interop.Access

function Access-Compile {
param (
    [Parameter(Mandatory=$TRUE,Position=1)][string]$source,
    [Parameter(Mandatory=$TRUE,Position=2)][string]$destination
)
    Write-Output "Starting MS Access"
    $access = New-Object -ComObject Access.Application
    $access.Visible = $FALSE
    $access.AutomationSecurity = 1

    if (!(Test-Path $source)) { Throw "Source '$source' not found" }
    if ((Test-Path $destination)) {
        Write-Output "File '$destination' already exists - deleting..."
        Remove-Item $destination
    }

    Write-Output "Compiling '$source' to '$destination'"
    $result = $access.SysCmd(603, $source, $destination)

    $result

    Write-Output "Exiting MS Access"
    $access.quit()
}

如果我进入PowerShell ISE并运行下面的命令,那么一切正常,并且创建了预期的输出:

PS C:>& "C:\Temp\PSLibrary.ps1"
PS C:>Access-Compile "C:\Working\Project.adp" "C:\Working\Project.ade"

然而,我似乎无法生成正确的hocus-pocus来从命令行运行,就像在自动构建中一样。例如,

powershell.exe -command "& \"C:\\Temp\\PSLibrary.ps1\" Access-Compile \"C:\\Temp\\Project.adp\" \"C:\\Temp\\Project.ade\""

我做错了什么?

2 个答案:

答案 0 :(得分:1)

对于复杂参数,您可以使用Powershell的-EncodedCommand参数。它将接受Base64编码的字符串。引号,斜杠等都不需要转义。

考虑一个将打印其参数的测试函数。像这样,

function Test-Function {
param (
    [Parameter(Mandatory=$TRUE,Position=1)][string]$source,
    [Parameter(Mandatory=$TRUE,Position=2)][string]$destination
)
    write-host "src: $source"
    write-host "dst: $destination"
}

创建命令以加载脚本和一些参数。像这样,

# Load the script and call function with some parameters
. C:\Temp\Calling-Test.ps1;  Test-Function "some\special:characters?" "`"c:\my path\with\spaces within.ext`""

命令语法正常后,将其编码为Base64格式。像这样,

[System.Convert]::ToBase64String([System.Text.Encoding]::UNICODE.GetBytes('. C:\Temp\Calling-Test.ps1;  Test-Function "some\special:characters?" "`"c:\my path\with\spaces within.ext`""'))

你会得到一个Base64字符串。像这样,

LgAgAEMAOgBcAFQAZQBtAHAAXABDAGEAbABsAGkAbgBnAC0AVABlAHMAdAAuAHAAcwAxADsAIAAgAFQAZQBzAHQALQBGAHUAbgBjAHQAaQBvAG4AIAAiAHMAbwBtAGUAXABzAHAAZQBjAGkAYQBsADoAYwBoAGEAcgBhAGMAdABlAHIAcwA/ACIAIAAiAGAAIgBjADoAXABtAHkAIABwAGEAdABoAFwAdwBpAHQAaABcAHMAcABhAGMAZQBzACAAdwBpAHQAaABpAG4ALgBlAHgAdABgACIAIgA=

最后,启动Powershell并将编码的字符串作为参数传递。像这样,

# The parameter string here is abreviated for readability purposes.
# Don't do this in production
C:\>powershell -encodedcommand LgAgA...
Output
src: some\special:characters?
dst: "c:\my path\with\spaces within.ext"

如果您以后想要反转Base64编码,请将其传递给解码方法。像这样,

$str = " LgAgA..."
[Text.Encoding]::Unicode.GetString([System.Convert]::FromBase64String($str))
# Output
. C:\Temp\Calling-Test.ps1;  Test-Function "some\special:characters?" "`"c:\my path\with\spaces within.ext`""

答案 1 :(得分:0)

像Bash这样的PowerShell可以采用单引号或双引号

PS C:\Users\Steven> echo "hello"
hello
PS C:\Users\Steven> echo 'hello'
hello

这可以减轻一些头痛,我认为你可以使用文字反斜杠而不会逃避。

要运行PowerShell,请选择

开始菜单 程序 附件 Windows Powershell Windows Powershell