You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何修改PowerShell脚本 过滤AD禁用账户仅同步活跃账号至SharePoint

修改方案:实现仅同步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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.29 11:51:19