【问题标题】:Trouble editing text files with powershell Get-Content and Set-Content使用 powershell Get-Content 和 Set-Content 编辑文本文件时遇到问题
【发布时间】:2021-01-29 14:44:40
【问题描述】:

目标:更新分布在服务器上的许多文件中的一行上的文本条目 摘要:作为数据中心之间应用程序迁移的一部分,最终用户桌面上的 .rdp 文件需要更新以指向其远程桌面服务器的新 IP 地址。所有 .rdp 文件都驻留在 Windows 服务器上的重定向文件夹 SMB 共享,我拥有管理访问权限。

Powershell 体验:最少。仍在努力思考变量、输出和管道的工作方式。

本来想用一行powershell代码来完成这个任务,但是卡住了,不得不用下面的两行代码制作脚本文件。 - 第 1 行:搜索文件夹结构中的所有 .rdp 文件,并将文件名的完整路径存储在变量中。由于用户往往会意外更改文件名,因此将检查每个文件,从而消除绝对的可预测性。 - 第 2 行:我想通过所有文件只用新地址替换两个特定 IP 地址的实例。然后将更改写入原始文件。

$Path = ls 'C:\Scripts\Replace-RDP\TESTFILES\' -Include *.rdp -Recurse -Force -ErrorAction SilentlyContinue | foreach fullname
$Path | (Get-Content -Path $Path) -Replace 'IPserver1','newIPserver1' -Replace 'IPserver2','newIPserver2' | Set-Content $Path -Force

已找到使用 Powershell 的大部分解决方案,但结果有问题。输出到屏幕时的第二行代码会正确更改内存中的内容。然而,写入文件的内容导致新的服务器 IP 地址被写入所有 rdp 文件,即使源 rdp 文件的目标 IP 地址与 -Replace 条件不匹配。

.rdp 中相关行的文本是:
完整地址:s:192.168.1.123 更改为: 完整地址:s:172.16.1.23

感谢您在到达终点时提供的所有帮助。花了几个小时从各种网站和代码 sn-ps 学习。

【问题讨论】:

  • 您的第二行不是有效的 PowerShell,管道中间不能有任意值表达式(如 (Get-Content ...) replace '...')。请使用您的实际代码更新
  • 为什么不在 .rdp 文件中使用 DNS 名称?然后您只需更新 DNS 记录,无需更改 .rdp 文件。
  • @Bill_Stewart 管理层不想使用他认为存在安全风险的 DNS 记录。如果我可以更改为 FQDN,我仍然需要此脚本来更改所有 .rdp 文件。
  • @MathiasR.Jessen 这就是我在脚本中的所有代码。第 2 行确实通过第一个管道正常工作,输出显示在 powershell 控制台中。
  • DNS 记录存在安全风险?互联网知道这件事吗?

标签: powershell pipe


【解决方案1】:

您需要跟踪正在阅读的每个文件,以便保存对该文件的更改。 Foreach-Object 使这个过程变得简单。在Foreach-Object 脚本块内,当前对象$_ 是每个文件的FullName 值。

$CurrentIP1 = '192\.168\.1\.123'
$CurrentIP2 = '192\.168\.1\.124'
$NewIP1 = '172.16.1.23'
$NewIP2 = '172.16.1.24'

$files = (Get-ChildItem 'C:\Scripts\Replace-RDP\TESTFILES\' -Filter *.rdp -Recurse -Force -File -ErrorAction SilentlyContinue).FullName
$files | Foreach-Object {
    if (($contents = Get-Content $_) -match "$CurrentIP1|$CurrentIP2") {
        $contents -replace $CurrentIP1,$NewIP1 -replace $CurrentIP2,$NewIP2 |
            Set-Content $_
    }
}

请注意,使用-File 开关打开Get-ChildItem(别名ls)仅输出文件。由于-replace 使用正则表达式进行匹配,因此您必须使用反斜杠转义文字. 字符。

【讨论】:

  • 此脚本更新工作正常且快速。我很欣赏处理变量的调整,使代码更易于阅读,删除第 1 行中的额外管道,并教我使用 $_ 对象将文件名传递到循环中的正确方法运行测试后,我看到了文件即使文件没有重大更改,时间戳也会全部更改。如果既没有找到 $CurrentIP1 也没有找到 $CurrentIP2 如何退出当前循环迭代?两个 currentIP 变量需要 \ 转义字符而 NewIP 变量不需要的原因是什么?
  • 我添加了一个版本,只更新包含 IP 的文件。
猜你喜欢
  • 2014-11-26
  • 1970-01-01
  • 2021-10-24
  • 1970-01-01
  • 1970-01-01
  • 2021-04-11
  • 1970-01-01
  • 2014-05-17
  • 2015-05-27
相关资源
最近更新 更多