如何使用CSV作为PowerShell脚本输入对日志文件进行脱敏?
日志IP地址脱敏与替换问题
我需要给供应商发送日志做技术支持,但日志不能包含主机名、IP等可识别信息,还要能追踪脱敏前后的对应关系。我的思路是先扫描日志提取IP,生成IP与脱敏标识的CSV,再用这个CSV替换日志里的IP。目前已经能生成CSV,但没法用它完成替换,现有脚本如下:
$ipNum = 1 $ipRedactions = "D:\ps_script\ipRedactions.csv" $ipPrefix = "Redacted-IP-" $ipRegex = "((25[0-5]|(2[0-4]|1\d|[1-9]|)\d)\.?){4}" $inputFile = "D:\ps_script\ipsample.txt" $fileContent = Get-Content $inputFile $outputFile = ($inputFile + "_Redacted") $ipMatches = $fileContent | Select-String $ipRegex -AllMatches | ForEach-Object { $_.Matches.Value } # 创建IP与脱敏标识的CSV $CSVPathTest = Test-Path $ipRedactions If ($CSVPathTest) {Remove-Item -Path $ipRedactions -Force} ForEach ($ipMatch in $ipMatches) { $CSVList += @([pscustomobject]{"IP Address"= $ipMatch; "Redaction"= $ipPrefix + $ipNum})| Export-Csv -Path $ipRedactions -Append -NoTypeInformation $ipNum = $ipNum + 1 } # 创建输出文件 $CSVPathTest = Test-Path $outputFile If ($CSVPathTest) {Remove-Item -Path $outputFile -Force} # TODO: 用CSV替换原文件中的IP ????
测试数据:
test 127.0.0.1test test 10.0.0.1 test test 172.28.69.77test blah blah blahtest test 15.26.32.159 test test 15.26.32.1594test blah blah serverhostname test
当前生成的CSV(存在重复IP对应不同标识的问题):
"IP Address","Redaction" "127.0.0.1","Redacted-IP-1" "10.0.0.1","Redacted-IP-2" "172.28.69.77","Redacted-IP-3" "15.26.32.159","Redacted-IP-4" "15.26.32.159","Redacted-IP-5"
解决方案
1. 修正CSV生成逻辑(避免重复IP分配多个标识)
原脚本会给同一个IP生成多个脱敏标识,不符合追踪需求,先修改这部分,给每个唯一IP分配唯一标识:
# 提取唯一IP并去重 $uniqueIps = $ipMatches | Select-Object -Unique # 创建CSV $CSVPathTest = Test-Path $ipRedactions If ($CSVPathTest) {Remove-Item -Path $ipRedactions -Force} $ipNum = 1 foreach ($ip in $uniqueIps) { [pscustomobject]@{ "IP Address" = $ip "Redaction" = "$ipPrefix$ipNum" } | Export-Csv -Path $ipRedactions -Append -NoTypeInformation $ipNum++ }
2. 修正IP正则表达式(避免匹配错误的IP)
原正则会匹配15.26.32.1594这类非法IP,换成更严谨的正则:
$ipRegex = '\b(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\b'
\b是单词边界,确保只匹配完整的IP,不会匹配带多余后缀的字符串。
3. 实现CSV驱动的替换逻辑
读取CSV创建哈希表,然后遍历文件内容进行替换:
# 读取CSV并创建哈希表(IP为键,脱敏标识为值) $redactionMap = @{} Import-Csv $ipRedactions | ForEach-Object { $redactionMap[$_."IP Address"] = $_.Redaction } # 处理文件内容并替换IP $redactedContent = $fileContent | ForEach-Object { # 用正则匹配IP,替换为对应的脱敏标识 [regex]::Replace($_, $ipRegex, { param($match) $redactionMap[$match.Value] ?? $match.Value # 找不到的IP保留原内容 }) } # 写入输出文件 $redactedContent | Set-Content $outputFile -Encoding UTF8
完整修正后的脚本
$ipNum = 1 $ipRedactions = "D:\ps_script\ipRedactions.csv" $ipPrefix = "Redacted-IP-" # 更严谨的IP正则,带单词边界避免匹配非法IP $ipRegex = '\b(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\b' $inputFile = "D:\ps_script\ipsample.txt" $fileContent = Get-Content $inputFile -Raw # 用-Raw读取整个文件,处理多行更高效 $outputFile = ($inputFile + "_Redacted") # 提取所有匹配的IP $ipMatches = $fileContent | Select-String $ipRegex -AllMatches | ForEach-Object { $_.Matches.Value } # 生成去重后的脱敏映射CSV $CSVPathTest = Test-Path $ipRedactions If ($CSVPathTest) {Remove-Item -Path $ipRedactions -Force} $uniqueIps = $ipMatches | Select-Object -Unique $ipNum = 1 foreach ($ip in $uniqueIps) { [pscustomobject]@{ "IP Address" = $ip "Redaction" = "$ipPrefix$ipNum" } | Export-Csv -Path $ipRedactions -Append -NoTypeInformation $ipNum++ } # 创建输出文件(如有则删除) If (Test-Path $outputFile) {Remove-Item -Path $outputFile -Force} # 读取映射表并替换IP $redactionMap = @{} Import-Csv $ipRedactions | ForEach-Object { $redactionMap[$_."IP Address"] = $_.Redaction } $redactedContent = [regex]::Replace($fileContent, $ipRegex, { param($match) $redactionMap[$match.Value] ?? $match.Value }) $redactedContent | Set-Content $outputFile -Encoding UTF8
运行后,生成的CSV会是每个唯一IP对应一个脱敏标识,输出文件中的IP会被正确替换,同时保留无法匹配的内容(比如15.26.32.1594不会被替换,因为它不是合法IP)。
内容的提问来源于stack exchange,提问作者BaldFeegle
相关产品推荐
相关产品推荐

