使用 Start-Process 和 ArgumentList 替换 Powershell 变量

Powershell variable replacement with Start-Process and ArgumentList

提问人:user13458199 提问时间:5/3/2020 更新时间:5/4/2020 访问量:430

问:

我有这个 powershell 代码,用于获取 FQDN 并将其保存到变量中......效果很好:

$FQDN=(Get-WmiObject win32_computersystem).DNSHostName.ToLower()+"."+(Get-WmiObject win32_computersystem).Domain

LogWrite“[+] 系统完全限定主机名已被检测为:$FQDN”

但是,当我去插入 FQDN 变量的字符串时,我无法让它正常工作。我尝试过回勾、双引号和单引号,但没有成功:

Start-Process -Wait $OUTPATH64 -ArgumentList '/s /v"/qn INSTALLDIR=\"C:\Program Files\IBM\WinCollect\" LOG_SOURCE_AUTO_CREATION_ENABLED=TRUE LOG_SOURCE_AUTO_CREATION_PARAMETERS=""Component1.AgentDevice=DeviceWindowsLog&Component1.Action=create&Component1.LogSourceName=REPLACEME&Component1.LogSourceIdentifier=REPLACEME&Component1.Dest.Name=test.domain.com&Component1.Dest.Hostname=test.domain.com&Component1.Dest.Port=514&Component1.Dest.Protocol=TCP&Component1.Log.Security=true&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.RemoteMachinePollInterval=3000&Component1.EventRateTuningProfile=Default+(Endpoint)&Component1.MinLogsToProcessPerPass=100&Component1.MaxLogsToProcessPerPass=150"""'

在您看到“REPLACEME”字符串的地方,我需要将其替换为 $FQDN 变量字符串。每当我使用反引号或双引号“$FQDN”甚至单引号“$FQDN”时,我都会得到“$FQDN”的文字字符串,并且代码片段实际上并没有进行变量替换。$FQDN

我在这里错过了什么?我什至还尝试过反引号双引号.我希望将 REPLACEME 字符串替换为实际主机名 + 域(如 hostname.domain.com)或$FQDN变量中设置的内容。ArgumentList 引号需要保持不变,因为我只能通过引用 ArgumentList 的方式以它以 ' 开头并以 “”“' 结尾的方式让我的命令正常工作。任何帮助将不胜感激。"$FQDN"

PowerShell 变量 行情

评论


答:

0赞 mklement0 5/3/2020 #1

PowerShell 中的引号字符串 () 是 PowerShell 中的逐字(文本)字符串 - 根据设计,不会对嵌入的变量引用或表达式执行扩展(插值)。'...'

要获得后者,您必须使用一个可扩展的字符串,该字符串是引号 ();例如,"..."
"...SourceName=$FQDN&Component1... "

由于您的字符串包含嵌入的字符,因此对我们来说,最简单的是可扩展字符串 () 的 here-string 变体:"@"<newline>...<newline>"@

Start-Process -Wait $OUTPATH64 -ArgumentList @"
/s /v"/qn INSTALLDIR=\"C:\Program Files\IBM\WinCollect\" LOG_SOURCE_AUTO_CREATION_ENABLED=TRUE LOG_SOURCE_AUTO_CREATION_PARAMETERS=""Component1.AgentDevice=DeviceWindowsLog&Component1.Action=create&Component1.LogSourceName=$FQDN&Component1.LogSourceIdentifier=$FQDN&Component1.Dest.Name=test.domain.com&Component1.Dest.Hostname=test.domain.com&Component1.Dest.Port=514&Component1.Dest.Protocol=TCP&Component1.Log.Security=true&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.RemoteMachinePollInterval=3000&Component1.EventRateTuningProfile=Default+(Endpoint)&Component1.MinLogsToProcessPerPass=100&Component1.MaxLogsToProcessPerPass=150"""
"@

如果使用常规双引号字符串 (),则必须将嵌入的字符转义为 (或 )。"...""`"""

有关 PowerShell 的字符串文本的详细信息,请参阅此答案的底部;官方帮助主题是about_Quoting_Rules

评论

1赞 user13458199 5/4/2020
谢谢你。这对我来说非常有效。非常感谢。
0赞 mklement0 5/4/2020
很高兴听到它,@user13458199;别客气。请允许我在下一条评论中为您提供对新手的标准建议:
0赞 stackprotector 5/3/2020 #2

这是它使用反向刻度的工作方式:

Start-Process -Wait $OUTPATH64 -ArgumentList "/s /v /qn INSTALLDIR=`"C:\Program Files\IBM\WinCollect\`" LOG_SOURCE_AUTO_CREATION_ENABLED=TRUE LOG_SOURCE_AUTO_CREATION_PARAMETERS=`"Component1.AgentDevice=DeviceWindowsLog&Component1.Action=create&Component1.LogSourceName=$FQDN&Component1.LogSourceIdentifier=$FQDN&Component1.Dest.Name=test.domain.com&Component1.Dest.Hostname=test.domain.com&Component1.Dest.Port=514&Component1.Dest.Protocol=TCP&Component1.Log.Security=true&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.RemoteMachinePollInterval=3000&Component1.EventRateTuningProfile=Default+(Endpoint)&Component1.MinLogsToProcessPerPass=100&Component1.MaxLogsToProcessPerPass=150`""

评论

0赞 user13458199 5/4/2020
谢谢托马斯。我很感激你的反馈。