Powershell每行替换一次文本

时间:2018-12-14 18:11:57

标签: powershell replace active-directory-group

我有一个Powershell脚本,我想尝试其中的一部分,因此输入的文本列出了它们所属的用户组。该PS脚本应该用我在活动目录中为其分配的组替换该组(我仅限于仅更改活动目录中的组)。我的问题是,当到达HR并替换HR时,它将继续构造并替换所有新HR,但是所有这些都替换了CHRL中的HR,因此我的团队现在看起来很疯狂。但是我一直在寻找它,并不是每行都如此。但是对于gilchrist而言,它将以HR的名义在其中添加一些内容。我可以做些什么来保持它的变化,还是必须将我的人力资源更改为人力资源?感谢您的帮助。

$lookupTable = @{
'Admin' = 'W_CHRL_ADMIN_GS,M_CHRL_ADMIN_UD,M_CHRL_SITE_GS'
'Security' = 'W_CHRL_SECURITY_GS,M_CHRL_SITE_GS'
'HR' = 'M_CHRL_HR_UD,W_CHRL_HR_GS,M_CHRL_SITE_GS'

    $original_file = 'c:\tmp\test.txt'
    $destination_file =  'c:\tmp\test2.txt'

    Get-Content -Path $original_file | ForEach-Object {
        $line = $_

        $lookupTable.GetEnumerator() | ForEach-Object {
            if ($line -match $_.Key)
            {
                $line = $line -replace $_.Key, $_.Value
            }
        }
       $line
    } | Set-Content -Path $destination_file

    Get-Content $destination_file

test.txt:

user,group 
john.smith,Admin 
joanha.smith,HR 
john.gilchrist,security
aaron.r.smith,admin
abby.doe,secuity 
abigail.doe,admin

2 个答案:

答案 0 :(得分:1)

您的输入似乎是CSV格式(尽管请注意,示例行中包含尾随空格,如果它们是实际数据的一部分,则必须处理)。 / p>

因此,使用Import-CsvExport-Csv 来读取/重写您的数据,这将提供一种更为简洁方便的解决方案:

Import-Csv test.txt |
  Select-Object user, @{ Name='group'; Expression = { $lookupTable[$_.group] } } |
    Export-Csv -NoTypeInformation -Encoding Utf8 test2.txt
  • Import-Csv读取CSV文件作为其属性与CSV列值相对应的自定义对象的集合;也就是说,根据您的情况,每个对象都有一个.user.name属性。

  • 因此,
  • $_.group仅健壮地报告抽象组名,您可以将其直接传递给您的查找哈希表。 Select-Object用于传递原始.user值,并使用 calculated属性将原始.group值替换为查找结果。

  • Export-Csv将自定义对象重新转换为CSV文件:

    • -NoTypeInformation禁止在输出文件顶部显示(通常无用)数据类型信息行。
    • 添加
    • -Encoding Utf8是为了防止潜在的数据丢失,因为默认情况下使用的是ASCII编码。
    • 请注意,Export-Csv盲目地用双引号所有字段值,无论是否需要;就是说,CSV读者应该能够解决这个问题(Import-Csv当然可以)。

关于您尝试过的事情

-replace运算符替换输入中所有出现的给定正则表达式(正则表达式)。

您的正则表达式相当于寻找(不区分大小写的)子字符串,这解释了为什么HR与用户名中的HR组名和子字符串hr都匹配gilchrist

一个简单的解决方法是在您的正则表达式中添加断言,以便子字符串仅在您需要的位置匹配;例如:,HR$仅在行(,)末尾的$之后匹配。

但是,为每个输入CSV行枚举哈希表键的方法效率低下,最好将组名分开并基于它进行直接查找:

# Split the row into fields.
$fields = $line -split ','

# Update the group value (last field)
$fields[-1] = $lookupTable[$fields[-1]]

# Rebuild the line
$line = $fields -join ','

请注意,您必须为标题行设置例外(例如,测试查找结果是否为空,如果是,则避免更新)。

答案 1 :(得分:0)

为什么不使用Import-CSV将文本文件加载为 CSV文件,并使用“,”作为分隔符? 这将使您拥有可以使用的Powershell对象。然后将其导出为CSV文本。如果我使用您的文件和查找表,则此代码可能会对您有所帮助:

$file = Import-Csv -Delimiter "," -Path "c:\ps\test.txt"

$lookupTable = @{
'Admin' = 'W_CHRL_ADMIN_GS,M_CHRL_ADMIN_UD,M_CHRL_SITE_GS'
'Security' = 'W_CHRL_SECURITY_GS,M_CHRL_SITE_GS'
'HR' = 'M_CHRL_HR_UD,W_CHRL_HR_GS,M_CHRL_SITE_GS'}


foreach ($i in $file) {

   #Compare and replace
   ...


}

Export-CSV $file -Delimiter ","

然后您可以遍历 $file 进行比较和替换。完成后,您也可以Export-CSV