输出文件时使用Powershell环境变量作为字符串

2024-01-08

我在用获取 WindowsAutopilotInfo https://www.powershellgallery.com/packages/Get-WindowsAutoPilotInfo/3.5生成计算机的序列号和哈希代码并将该信息导出为 CSV。

这是我通常使用的代码:

new-item "c:\Autopilot_Export" -type directory -force

Set-Location "C:\Autopilot_Export"

Get-WindowsAutopilotInfo.ps1 -OutputFile Autopilot_CSV.csv

Robocopy C:\Autopilot_Export \\Zapp\pc\Hash_Exports /copyall

这会将名为“Autopilot_CSV.csv”的 CSV 文件输出到C:\Autopilot_Export目录,然后 Robocopy 将其复制到上面列出的 Hash_Exports 文件夹内的网络共享驱动器。在上面的代码中,如果我手动输入“test”、“123”、“ABC”等并替换“Autopilot_CSV”,它也会在所有这些名称下输出一个 CSV。所以看起来像获取 WindowsAutopilotInfo https://www.powershellgallery.com/packages/Get-WindowsAutoPilotInfo/3.5将创建一个 CSV 文件并使用您传入的任何字符串保存文件名。伟大的。

但是,我在多台不同的计算机上运行此脚本,并且我希望将导出的 CSV 命名为运行它的计算机所特有的名称,以便在复制后我可以轻松识别它。我正在尝试传递环境变量的值$env:computername作为 CSV 的字符串输入,但它不起作用。

这是我尝试使用的代码:

new-item "c:\Autopilot_Export" -type directory -force

Set-Location "C:\Autopilot_Export"

Get-WindowsAutopilotInfo.ps1 -OutputFile $env:computername.csv

Robocopy C:\Autopilot_Export C:\Users\danieln\Desktop /copyall

此代码根本不生成 CSV 文件。为什么不?

我是否对 Powershell 中如何使用环境变量有一个基本的误解?$env:computername似乎返回计算机名称的字符串,但我无法将其传递到 Get-WindowsAutopilotInfo 并保存它,但它will如果我手动输入一个字符串作为输入,则可以工作。

我也尝试过将其设置为变量$computername = [string]$env:computername刚刚过去$computername在 .CSV 之前,这似乎也不起作用。根据文档,环境变量显然已经是字符串了。

我错过了什么吗?

Thanks!


js2010 的回答 https://stackoverflow.com/a/66160252/45375显示有效的解决方案:使用"..."- 引用,即可扩展字符串 https://stackoverflow.com/a/40445998/45375 明确地.

养成使用是一个好习惯"..." 明确地 around 命令参数那是字符串含有变量引用(例如"$HOME/projects") 或子表达式(例如,"./folder/$(Get-Date -Format yyyy-MM)")

While such compound string arguments generally do not require double-quoting[1] - because they are implicitly treated as if they were "..."-enclosed - in certain cases they do, and when they do is not obvious and therefore hard to remember:

这个答案 https://stackoverflow.com/a/41254359/45375详细说明了令人惊讶的复杂规则,但以下是如果你这样做的话,有两个值得注意的陷阱not use "...":

  • 如果一个复合参数以。。开始子表达式 ($(...)),其输出通过作为一个单独的论点; e.g. Write-Output $(Get-Location)/folder passes two论点Write-Output: 的结果$(Get-Location)和字面意思/folder

  • 如果一个复合参数以。。开始变量引用and后面跟着什么语法上看起来像(a) 一个财产访问权 (e.g., $PSVersionTable.PsVersion) 或 (b) a方法调用 (e.g., $PSHome.Tolower()) it is 就这样执行,即作为表达(而不是被视为变量引用后跟文字部分)。

    • 除了#1:这样的论点不一定是string,但无论属性值或方法调用返回值是什么数据类型。

    • Aside #2: A compound string that starts with a quoted string (whether single- or double-quoted) does not work, because the quoted string at the start is also considered an expression, like property access and method calls, so that what comes after is again passed as separate argument(s). Therefore, you can only have a compound strings consisting of a mix of quoted and unquoted substrings if the compound string starts with an unquoted substring or a non-expression variable reference.[2]

后者是这个案例中发生了什么:

  • Unquoted $env:computername.csv被解释为尝试访问一个名为csv关于存储在(环境)变量中的对象$env:computername,并且自从[string]存储在那里的实例没有csv属性,表达式计算为$null.

  • By forcingPowerShell 通过以下方式将此值解释为可扩展字符串"...", 通常插值规则 https://stackoverflow.com/a/40445998/45375适用,这意味着.csv确实被视为literal(因为属性访问需要使用$(...)在可扩展字符串中)。


[1] Quoting is required for strings that contain metacharacters such as spaces.
For values to be treated verbatim, '...' quoting is the better choice (see the bottom section of this answer https://stackoverflow.com/a/55614306/45375 for an overview of PowerShell string literals).
Also, using neither double- nor single-quoting and individually `-escaping metacharacters is another option (e.g. Write-Output C:\Program` Files.

[2] For instance, Write-Output a"b`t"'`c' and Write-Output $HOME"b`t"'`c' work as intended, whereas Write-Output "b`t"'`c' and Write-Output $HOME.Length"b`t"'`c' do not (the latter two each pass 3 arguments). The workaround is to either use a single "..." string with internal `-escaping as necessary (e.g. Write-Output "${HOME}b`t``c") or to use string-concatenation expression with + enclosed in (...) (e.g. Write-Output ($HOME + "b`t" + '`c'))

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

输出文件时使用Powershell环境变量作为字符串 的相关文章

随机推荐