【问题标题】:PowerShell execution fails due to space in directory name由于目录名称中有空格,PowerShell 执行失败
【发布时间】:2018-09-02 19:30:29
【问题描述】:

我收到了一个 PowerShell 脚本,该脚本执行以安装位于同一目录中的可执行文件。这被打包到 SCCM(系统中心配置管理器)中以进行部署。但是,如果在包部署期间,推送包的临时目录在文件路径中的任何位置都有空格,则部署失败。

例如:

  1. C:\temp\deployment -- 这将通过,软件将安装。
  2. C:\temp\deployment 1\ -- 这将失败,因为部署和 1 之间存在空间
  3. C:\temporary directory\deployment\ -- 这将失败,因为临时目录和目录之间存在空间。

这是我怀疑正在执行安装的部分代码:

if ($softwarename -eq "Not Installed") {
    Write-Output "Installing softwarename..."
    #   Build a massive softwarename installation line 
    $tempFile = [System.IO.Path]::GetTempFileName() + ".cmd"
    $installLine = "$scriptPath\softwarename.exe /s /v`"/qn INSTALLDIR=\`"C:\Program Files\directoryname\softwarename\`" AUTHTOKEN=REDACTED FULLCONSOLEADDRESS=$dest`:8413 HOSTNAME=$Env:COMPUTERNAME LOG_SOURCE_AUTO_CREATION_ENABLED=True LOG_SOURCE_AUTO_CREATION_PARAMETERS=`"`"Component1.AgentDevice=DeviceWindowsLog&Component1.Action=create&Component1.LogSourceName=$env:COMPUTERNAME&Component1.LogSourceIdentifier=$env:COMPUTERNAME&Component1.Log.Security=true&Component1.Filter.Security.Enabled=true&Component1.Filter.Security.Param=5156&Component1.Filter.Security.Type=Blacklist&Component1.Log.System=true&Component1.Log.Application=true&Component1.Log.DNS+Server=false&Component1.Log.File+Replication+Service=false&Component1.Log.Directory+Service=false&Component1.Destination.Name=$dest&Component1.RemoteMachinePollInterval=300&Component1.EventRateTuningProfile=High+Event+Rate+Server&Component1.MinLogsToProcessPerPass=1250&Component1.MaxLogsToProcessPerPass=1875`"`"`""
    $installLine | Out-File -Encoding ascii -filepath $tempFile
    Write-Output $tempFile
    cmd.exe /c $tempFile
} else {
    if ($psversiontable.psversion.major -gt 2) {
        $props=ConvertFrom-StringData (Get-Content "c:\Program Files\directoryname\softwarename\config\install_config.txt" -Raw)
        if ($props.ConfigurationServer -eq $dest) {
            Write-Output "Configuration server is correct - no action"
        } else {
            Stop-Service (Get-Service -ErrorAction SilentlyContinue softwarename)
            $props.ConfigurationServer=$dest
            $props.StatusServer=$dest
            $props.GetEnumerator() | % { "$($_.Name)=$($_.Value)" } | Out-File -Encoding ascii -filepath "c:\Program Files\directoryname\softwarename\config\install_config.txt"
            del "c:\Program Files\directoryname\softwarename\config\ConfigurationServer.PEM" 
            Start-Service (Get-Service -ErrorAction SilentlyContinue softwarename)
            Write-Output "Configuration server reset to $dest"
        } 
    } else {
        Write-Output "Powershell version does not support the reset functionality."
    }

我怀疑以下两行是问题的原因:

$tempFile = [System.IO.Path]::GetTempFileName() + ".cmd"
    $installLine = "$scriptPath\softwarename.exe /s /v`"/qn

我怀疑由于执行需要确切的路径,并且目录路径中的“空格”会导致“找不到路径”(有趣的是,在我的 Windows 10 机器上,更改目录 [cd] 命令可以在没有将带空格的文件路径放在引号中的情况下工作- "" -- 这让我相信我完全错了,但是在这一点上我没有其他东西可看)。

谁能协助添加参数以确保为要执行的 .cmd 文件生成的补丁没有空格?

我试图通过添加一个批处理文件来修补这个问题,该批处理文件在执行之前将包复制到一个静态目录。但是,这无法通过 SCCM 进行部署。

【问题讨论】:

  • 我已经在这里粘贴了代码,如果这里的格式很难理解的话-pastebin.com/6KBqxgNG
  • $installLine 实际上是 976 个字符吗?你知道这在 PowerShell 脚本之外可以正常工作吗?

标签: powershell powershell-2.0 sccm quoting


【解决方案1】:

为了从包含空格的路径的批处理文件中调用程序,该路径必须包含在"..." 中:

# PowerShell string that constructs the command line to write to the batch file.
$installLine = "`"$scriptPath\softwarename.exe`" ..."

`" 是您在 PowerShell 的 "..." 字符串中嵌入文字 " 的方式。

相比之下,从路径包含空格的批处理文件中调用cd 也可以包含"...",但是:

  • 只有在没有歧义的情况下才有可能,因为cd 只需要一个 操作数(目标目录)。
  • 由于与所有其他命令必须如何处理带空格的参数不一致,因此支持这一点从来都不是一个好主意。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2018-08-07
    • 2022-06-29
    • 1970-01-01
    • 2019-04-02
    • 1970-01-01
    • 2022-08-09
    • 1970-01-01
    • 2013-01-30
    相关资源
    最近更新 更多