PowerShell脚本提取LDIF无goEmpid记录为空文件问题排查
问题排查与解决:LDIF文件提取无goEmpid记录脚本失效
问题背景
需要编写PowerShell脚本从LDIF文件中提取不含goEmpid属性的记录,但执行脚本后控制台无输出且输出文件为空。
LDIF文件示例内容
dn: cn=username,ou=organisationname,ou=org-ca,ou=go-pki,o=finance of organisation,st=on,c=ca, cn:username mail:username@org.ca uid: username goEmpid:2273773 dn: cn=username1,ou=organisationname,ou=org-ca,ou=go-pki,o=finance of organisation,st=on,c=ca, cn:username1 mail:username1@org.ca uid: username1 dn: cn=username2,ou=organisationname,ou=org-ca,ou=go-pki,o=finance of organisation,st=on,c=ca, cn:username2 mail:username2@org.ca uid: username2 dn: cn=username3,ou=organisationname,ou=org-ca,ou=go-pki,o=finance of organisation,st=on,c=ca, cn:username3 mail:username3@org.ca uid: username3 goEmpid:2273776
用户原脚本
# the path to LDIF file $ldifFilePath = "C:\Users\91701\Desktop\pki.ldif" # the path for the output file $outputFilePath = "C:\Users\91701\Desktop\output.txt" # Reading the content of the LDIF file $ldifContent = Get-Content $ldifFilePath -Raw # Split LDIF content into individual records $ldifRecords = $ldifContent -split "^\s*$" | Where-Object { $_ -match '\S' } # Initializing an empty array to store records with missing 'goEmpid' $missingGoEmpidRecords = @() # Loop through each record and check if 'goEmpid' is missing foreach ($record in $ldifRecords) { if ($record -notmatch 'goEmpid') { $missingGoEmpidRecords += @" Record with missing 'goEmpid': $record ------------------------- "@ } } # Output the missing 'goEmpid' records to the console Write-Output $missingGoEmpidRecords # Save the output to a file $missingGoEmpidRecords | Out-File -FilePath $outputFilePath -Append
失效原因分析
- 正则拆分逻辑错误:PowerShell默认的
-split使用单行模式,^和$仅匹配整个字符串的首尾,无法识别每行的空行分隔符,导致所有LDIF记录被合并为一个元素。 - 匹配判断失效:由于拆分失败,整个文件内容被当作单条记录处理,而文件中存在
goEmpid字段,因此$record -notmatch 'goEmpid'返回false,没有记录被加入结果数组。
修复后的脚本
# LDIF文件路径 $ldifFilePath = "C:\Users\91701\Desktop\pki.ldif" # 输出文件路径 $outputFilePath = "C:\Users\91701\Desktop\output.txt" # 读取文件内容 $ldifContent = Get-Content $ldifFilePath -Raw # 使用多行正则拆分空行分隔的记录 $ldifRecords = [regex]::Split($ldifContent, '(?m)^\s*$\n?') | Where-Object { $_ -match '\S' } # 初始化结果数组 $missingGoEmpidRecords = @() foreach ($record in $ldifRecords) { # 精准匹配goEmpid属性行 if ($record -notmatch 'goEmpid:') { $missingGoEmpidRecords += @" Record with missing 'goEmpid': $record ------------------------- "@ } } # 控制台输出结果 Write-Output $missingGoEmpidRecords # 写入输出文件(覆盖模式,避免重复内容) $missingGoEmpidRecords | Out-File -FilePath $outputFilePath -Encoding utf8
关键修复点
- 使用
[regex]::Split并指定(?m)多行模式,让^和$匹配每行首尾,正确拆分空行分隔的LDIF记录。 - 将匹配条件调整为
goEmpid:,避免误匹配包含该字符串的其他字段。 - 把
Out-File的-Append改为默认覆盖模式,防止多次执行时输出文件内容重复。
内容的提问来源于stack exchange,提问作者monica ar
相关产品推荐
相关产品推荐

