Powershell ForEach 替换(在 AD 中批量更改主 SMTP)
Powershell ForEach replace (Bulk change primary SMTP in AD)
我需要从某个OU的用户批量切换AD中的主SMTP地址。
挑战;
User1
smtp:first.last@domain1.com
smtp:flast@domain1.com
SMTP:first.last@domain2.net
smtp:flast@domain2.net
我需要将 first.last@domain1 设为主 SMTP。
到此为止;
$proxies = $null
Get-ADUser -Filter * -SearchBase "OU=users_test,OU=Test,DC=test,DC=local" -Properties name,mail,ProxyAddresses |
Foreach {
$proxies = $_.ProxyAddresses |
ForEach-Object{
$a = $_ -replace 'SMTP','smtp'
if($a -match 'domain1.com'){
$a -replace 'smtp','SMTP'
Write-Host $a
}else{
$a
}
}
$_.ProxyAddresses = $proxies
#Set-ADUser -instance $_
Write-host $proxies
}
问题:
当我 运行 上面的脚本时,它显然通过将 smtp 替换为 SMTP 在它找到的所有匹配 domain1.com.
问:怎样才能做到只替换一个?
我希望我能很好地解释自己。预先感谢您提供的任何帮助
因为没有必要选择一个特定的 domain1.com 地址,试试这个。
我添加了一个标志变量来为每个用户设置一次主地址。
此外,我切换到 -like 运算符,因为 -match 运算符不是必需的,如果使用不当只会产生更多开销。
并且我已将“字符串开头”正则表达式字符添加到您的替换部分(-replace 也使用正则表达式模式)
Get-ADUser -Filter * -SearchBase 'OU=users_test,OU=Test,DC=test,DC=local' -Properties name, mail, ProxyAddresses |
ForEach-Object {
# flag to avoid further processing after first match
$userDone = $false
$proxies = $_.ProxyAddresses |
ForEach-Object {
$proxyAddress = $_ -replace '^SMTP', 'smtp'
if (!$userDone -and $proxyAddress -like '*@domain1.com') {
$proxyAddress -replace '^smtp', 'SMTP'
$userDone = $true
} else {
$proxyAddress
}
}
$_.ProxyAddresses = $proxies
#Set-ADUser -instance $_
Write-Host $proxies
}
更新 2021-01-13
这是根据您在下方评论中的要求进行的更新。
Could you show me how I could use the same script that would choose first.last@domain1.com. The ForEach should change to primary the one that has first.last.
现在正则表达式更有意义 ;)
该代码未针对 Active Directory 进行测试,但应该可以工作。
简而言之正则表达式模式:
(?i) >case-insensitive match (=regex option)
^ >start of string
(?: >non-capturing group (capturing is not required in your case)
smtp: >starts with 'smtp:'
[^\.\@]+ >matches any char at least once excluding '.' and '@'
\. >matches '.' once
[^\.\@]+ >matches any char at least once excluding '.' and '@'
@domain1\.com >matches '@domain1.com'
)
$ >end of string
更多详情请看:https://regex101.com/r/atKdSw/1/
当由于任何原因没有匹配时,我另外添加了警告。然后地址不会返回到源 属性(地址保持原始状态)。
# pattern matches only addresses with format "*.*@domain.com" --> <anythingButDotOr(at)>.<anythingButDotOr(at)>@domain.com
$newPrimaryAddressMatchPattern = '(?i)^(?:smtp:[^\.\@]+\.[^\.\@]+@domain1\.com)$'
Get-ADUser -Filter * -SearchBase 'OU=users_test,OU=Test,DC=test,DC=local' -Properties name, mail, ProxyAddresses |
ForEach-Object {
# flag to avoid further processing after first match
$userDone = $false
$proxies = $_.ProxyAddresses |
ForEach-Object {
$proxyAddress = $_ -replace '^SMTP', 'smtp'
if (!$userDone -and $proxyAddress -match $newPrimaryAddressMatchPattern) {
$proxyAddress -replace '^smtp', 'SMTP'
$userDone = $true
} else {
$proxyAddress
}
}
if (!$userDone) {
# if no address matched the pattern required for setting the new primary one
Write-Warning "Unable to set new primary address for $($_.UserPrincipalName) | $($_.CanonicalName)!"
} else {
$_.ProxyAddresses = $proxies
}
#Set-ADUser -instance $_
Write-Host $proxies
}
我需要从某个OU的用户批量切换AD中的主SMTP地址。
挑战;
User1
smtp:first.last@domain1.com
smtp:flast@domain1.com
SMTP:first.last@domain2.net
smtp:flast@domain2.net
我需要将 first.last@domain1 设为主 SMTP。
到此为止;
$proxies = $null
Get-ADUser -Filter * -SearchBase "OU=users_test,OU=Test,DC=test,DC=local" -Properties name,mail,ProxyAddresses |
Foreach {
$proxies = $_.ProxyAddresses |
ForEach-Object{
$a = $_ -replace 'SMTP','smtp'
if($a -match 'domain1.com'){
$a -replace 'smtp','SMTP'
Write-Host $a
}else{
$a
}
}
$_.ProxyAddresses = $proxies
#Set-ADUser -instance $_
Write-host $proxies
}
问题:
当我 运行 上面的脚本时,它显然通过将 smtp 替换为 SMTP 在它找到的所有匹配 domain1.com.
问:怎样才能做到只替换一个?
我希望我能很好地解释自己。预先感谢您提供的任何帮助
因为没有必要选择一个特定的 domain1.com 地址,试试这个。
我添加了一个标志变量来为每个用户设置一次主地址。 此外,我切换到 -like 运算符,因为 -match 运算符不是必需的,如果使用不当只会产生更多开销。
并且我已将“字符串开头”正则表达式字符添加到您的替换部分(-replace 也使用正则表达式模式)
Get-ADUser -Filter * -SearchBase 'OU=users_test,OU=Test,DC=test,DC=local' -Properties name, mail, ProxyAddresses |
ForEach-Object {
# flag to avoid further processing after first match
$userDone = $false
$proxies = $_.ProxyAddresses |
ForEach-Object {
$proxyAddress = $_ -replace '^SMTP', 'smtp'
if (!$userDone -and $proxyAddress -like '*@domain1.com') {
$proxyAddress -replace '^smtp', 'SMTP'
$userDone = $true
} else {
$proxyAddress
}
}
$_.ProxyAddresses = $proxies
#Set-ADUser -instance $_
Write-Host $proxies
}
更新 2021-01-13
这是根据您在下方评论中的要求进行的更新。
Could you show me how I could use the same script that would choose first.last@domain1.com. The ForEach should change to primary the one that has first.last.
现在正则表达式更有意义 ;)
该代码未针对 Active Directory 进行测试,但应该可以工作。
简而言之正则表达式模式:
(?i) >case-insensitive match (=regex option)
^ >start of string
(?: >non-capturing group (capturing is not required in your case)
smtp: >starts with 'smtp:'
[^\.\@]+ >matches any char at least once excluding '.' and '@'
\. >matches '.' once
[^\.\@]+ >matches any char at least once excluding '.' and '@'
@domain1\.com >matches '@domain1.com'
)
$ >end of string
更多详情请看:https://regex101.com/r/atKdSw/1/
当由于任何原因没有匹配时,我另外添加了警告。然后地址不会返回到源 属性(地址保持原始状态)。
# pattern matches only addresses with format "*.*@domain.com" --> <anythingButDotOr(at)>.<anythingButDotOr(at)>@domain.com
$newPrimaryAddressMatchPattern = '(?i)^(?:smtp:[^\.\@]+\.[^\.\@]+@domain1\.com)$'
Get-ADUser -Filter * -SearchBase 'OU=users_test,OU=Test,DC=test,DC=local' -Properties name, mail, ProxyAddresses |
ForEach-Object {
# flag to avoid further processing after first match
$userDone = $false
$proxies = $_.ProxyAddresses |
ForEach-Object {
$proxyAddress = $_ -replace '^SMTP', 'smtp'
if (!$userDone -and $proxyAddress -match $newPrimaryAddressMatchPattern) {
$proxyAddress -replace '^smtp', 'SMTP'
$userDone = $true
} else {
$proxyAddress
}
}
if (!$userDone) {
# if no address matched the pattern required for setting the new primary one
Write-Warning "Unable to set new primary address for $($_.UserPrincipalName) | $($_.CanonicalName)!"
} else {
$_.ProxyAddresses = $proxies
}
#Set-ADUser -instance $_
Write-Host $proxies
}