如何修改PowerShell脚本 过滤AD禁用账户仅同步活跃账号至SharePoint
核心问题
原脚本直接遍历SharePoint User Profile存储的全量用户配置文件,未关联校验Active Directory侧的账户状态,因此会同步已禁用、长期未登录的非活跃账户。
修改前置要求
运行脚本的SharePoint服务器需提前安装AD PowerShell模块,执行以下命令安装(需管理员权限):
Install-WindowsFeature RSAT-AD-PowerShell
关键修改逻辑
在原有脚本遍历用户配置文件的流程中,新增过滤逻辑,不符合要求的账户直接跳过同步:
- 加载Active Directory PowerShell模块
- 从用户配置文件的
AccountName字段提取AD账户名,查询AD侧账户属性 - 按规则过滤不符合要求的账户:
- 跳过AD中不存在的孤立用户配置文件
- 跳过
Enabled属性为$false的已禁用账户 - 跳过超过指定天数未登录的非活跃账户(默认阈值90天,可按需调整)
具体代码修改点
1. 脚本开头新增AD模块加载逻辑
在原有SharePoint PSSnapin加载代码后,新增以下内容:
# 加载AD模块 if (-not (Get-Module -Name ActiveDirectory -ListAvailable)) { throw "当前服务器未安装Active Directory PowerShell模块,请先安装RSAT-AD-PowerShell功能" } Import-Module ActiveDirectory -ErrorAction Stop # 配置非活跃账户阈值:90天未登录判定为非活跃 $inactiveThreshold = (Get-Date).AddDays(-90)
2. 遍历用户配置文件时新增状态校验
在原代码拿到$AccountName变量、原有部门和经理非空判断之前,新增AD账户校验逻辑,不符合条件直接continue跳过当前用户:
# 提取AD samAccountName(兼容域\用户名、i:0#.w|域\用户名两种格式) if ($AccountName -match '(?<=\\)[^\\]+$') { $samAccountName = $Matches[0] } else { # 账户名格式不符合规范,直接跳过 continue } # 查询AD账户状态 try { $adUser = Get-ADUser -Identity $samAccountName -Properties Enabled, LastLogonDate -ErrorAction Stop } catch { # AD中不存在该账户,跳过 continue } # 过滤已禁用账户 if (-not $adUser.Enabled) { continue } # 过滤非活跃账户:LastLogonDate为空或早于阈值则跳过 if (-not $adUser.LastLogonDate -or $adUser.LastLogonDate -lt $inactiveThreshold) { continue }
修改后完整脚本
#if not already added if ((Get-PSSnapin "Microsoft.SharePoint.PowerShell" -ErrorAction SilentlyContinue) -eq $null) { Add-PSSnapin "Microsoft.SharePoint.PowerShell" } # 加载AD模块 if (-not (Get-Module -Name ActiveDirectory -ListAvailable)) { throw "当前服务器未安装Active Directory PowerShell模块,请先安装RSAT-AD-PowerShell功能" } Import-Module ActiveDirectory -ErrorAction Stop # 配置非活跃账户阈值:90天未登录判定为非活跃,可按需调整天数 $inactiveThreshold = (Get-Date).AddDays(-90) $site = new-object Microsoft.SharePoint.SPSite("https://portal.company.gov.sa/"); $ServiceContext = [Microsoft.SharePoint.SPServiceContext]::GetContext($site); #Get UserProfileManager from the My Site Host Site context $ProfileManager = new-object Microsoft.Office.Server.UserProfiles.UserProfileManager($ServiceContext) $AllProfiles = $ProfileManager.GetEnumerator() # Open SharePoint List $spWeb = Get-SPWeb "https://my.gac.gov.sa/" $spData = $spWeb.GetList("Lists/EmployeesDirectory/") $spDepartments = $spWeb.GetList("Lists/Departments/") $total=0; $withErros=0; foreach($profile in $AllProfiles) { try { $DisplayName = $profile.DisplayName $WorkEmail = $profile[[Microsoft.Office.Server.UserProfiles.PropertyConstants]::WorkEmail] $AccountName = $profile[[Microsoft.Office.Server.UserProfiles.PropertyConstants]::AccountName] $Department = $profile[[Microsoft.Office.Server.UserProfiles.PropertyConstants]::Department] $Position = $profile.JobTitle $LastName = $profile[[Microsoft.Office.Server.UserProfiles.PropertyConstants]::LastName] $FirstName = $profile[[Microsoft.Office.Server.UserProfiles.PropertyConstants]::FirstName] $FullName= "$FirstName $LastName" $PreferredName = $profile[[Microsoft.Office.Server.UserProfiles.PropertyConstants]::PreferredName] $WorkPhone =$profile[[Microsoft.Office.Server.UserProfiles.PropertyConstants]::WorkPhone] $Manager = $profile[[Microsoft.Office.Server.UserProfiles.PropertyConstants]::Manager] $JobTitleArabic=$profile["JobTitleArabic"]; # 新增:AD账户状态校验 # 提取AD samAccountName(兼容域\用户名、claims身份格式) if ($AccountName -match '(?<=\\)[^\\]+$') { $samAccountName = $Matches[0] } else { continue } # 查询AD账户信息 try { $adUser = Get-ADUser -Identity $samAccountName -Properties Enabled, LastLogonDate -ErrorAction Stop } catch { # AD中不存在的账户直接跳过 continue } # 过滤已禁用账户 if (-not $adUser.Enabled) { continue } # 过滤非活跃账户 if (-not $adUser.LastLogonDate -or $adUser.LastLogonDate -lt $inactiveThreshold) { continue } if($Department -ine '' -and $Manager -ine ''){ $total++; $departmnetItem = $spDepartments.Items | Where {$_["FF_TitleEn"] -eq $Department} # Add properties to this list item $user=$spWeb.EnsureUser($AccountName); write-host $DisplayName "|" $AccountName "|" $Department "|" $Position "|" $PreferredName "|" $WorkPhone "|" $Manager ; if($user.ID -gt 0) { #Query to filter List Items which contains user account $SPQuery = new-object Microsoft.SharePoint.SPQuery $Query = "<Where><Eq><FieldRef Name='FF_Emlpoyee' LookupId='TRUE'/><Value Type='User'>$($user.ID)</Value></Eq></Where>" $SPQuery.Query=$Query #Filter List Items by Query $ListItems = $spData.GetItems($SPQuery) if($ListItems.Count -gt 0) { $newItem=$ListItems[0]; } else { #Create a new item $newItem = $spData.Items.Add() } $newItem["FF_Emlpoyee"] = $user.ID; $newItem["Title"] = $PreferredName if($WorkPhone -ine '') { $newItem["FF_ExtensionNumber"] = $WorkPhone } try { if($Manager -ine $null) { $userManager=$spWeb.EnsureUser($Manager); $newItem["FF_Manager"] = $userManager.ID } } catch { write-host -ForegroundColor Red "Manager Not Found fro : " $user } $newItem["FF_Position"] = $Position if($JobTitleArabic -ine '') { $newItem["FF_PositionAr"] = $JobTitleArabic } $newItem["FF_FullNameAr"] = $FullName $newItem["FF_Department"] = $departmnetItem.ID $newItem.Update() Write-Host "---------------------------------"; } $user=$null } } catch { write-host -ForegroundColor Red $_.Exception $withErros+=1 } } Write-Host "Total: " $total; Write-Host "withErros: " $withErros
可选调整说明
- 若不需要过滤长期未登录的非活跃账户,直接删除对应
LastLogonDate判断的代码块即可 - 非活跃阈值可通过修改
AddDays(-90)中的数值调整,例如设置为AddDays(-180)即180天未登录判定为非活跃 - 若需要额外过滤其他状态的账户(如密码过期、账户锁定),可在Get-ADUser时增加对应属性,补充判断逻辑即可
内容的提问来源于stack exchange,提问作者Imran Jalali
相关产品推荐
相关产品推荐

