文件共享与访问

用于检索配置文件期限的脚本 - Windows Server

· 52CE 我爱测

假设已将“删除系统重启(https://gpsearch.azurewebsites.net/2583)时早于指定天数的用户配置文件”组策略设置为在系统启动时删除过期的配置文件。 本文提供了一个示例脚本,可帮助确定何时考虑删除配置文件,因为应用组策略。 注意 Windows Management Instrumentation (WMI) 提供程序还可用于配置配置文件处理,并且可以替代组策略设置。 Microsoft System Center Confi

假设已将“删除系统重启时早于指定天数的用户配置文件”组策略设置为在系统启动时删除过期的配置文件。 本文提供了一个示例脚本,可帮助确定何时考虑删除配置文件,因为应用组策略。

注意

Windows Management Instrumentation (WMI) 提供程序还可用于配置配置文件处理,并且可以替代组策略设置。 Microsoft System Center Configuration Manager(SCCM)是一个可以执行此操作的软件示例。

适用于: Windows 10 版本 1809、Windows 11、Windows Server 2019 和更高版本的 Windows

详细信息

Windows 10 版本 1809、Windows Server 2019(版本 1809)和更高版本更改配置文件期限的确定方式,并删除对ntuser.dat文件的修改时间戳的依赖。 Windows 现在使用带时间戳的注册表值来表示加载时间、卸载时间和可能的清理时间。 ntuser.dat时间戳现在用作回退决策。

以下注册表值跟踪配置文件服务上次加载配置文件,并用于验证 Unload 和 Cleanup 值:

  • LocalProfileLoadTimeLow
  • LocalProfileLoadTimeHigh

以下注册表值跟踪配置文件服务上次卸载配置文件:

  • LocalProfileUnLoadTimeLow
  • LocalProfileUnLoadTimeHigh

以下注册表值跟踪清理时间。 如果其他任一值无效或不存在,并且 ntuser.dat 时间戳在启动期间没有足够的时间删除,并且配置了策略,则从此时间戳计算年龄。 如果用户在设置注册表值时登录,则会删除注册表值,并跟踪将还原到其他值。

  • LocalProfileCleanupCheckTimeLow
  • LocalProfileCleanupCheckTimeHigh

重要

此示例脚本在任何Microsoft标准支持计划或服务下都不受支持。

示例脚本按原样提供,没有任何保证。 Microsoft进一步否认所有默示担保,包括不限于适销性或针对特定用途的适用性的任何默示担保。

示例脚本和文档的使用或性能导致的整个风险依然存在。 在任何情况下,不得Microsoft、其作者或参与创建、制作或交付脚本的任何其他人对任何损害负责(包括但不限于业务利润损失、业务中断、业务中断、业务信息损失或其他经济损失)因使用或无法使用示例脚本或文档而导致的损害。 即使Microsoft被告知这种损害的可能性。

脚本

Function TranslateSID2Name
{
    param(
        [string]$sid
    )

    try
    {
        $osid = New-Object System.Security.Principal.SecurityIdentifier( $sid )
        $osid.Translate([System.Security.Principal.NTAccount])
    }
    catch
    {
        "<Unresolved>"
    }
}

Function ConvertToDate
{
    param(
        [uint32]$lowpart,
        [uint32]$highpart
    )

    $ft64 = ( [UInt64]$highpart -shl 32) -bor $lowpart
    [datetime]::FromFileTime( $ft64 )
}

Function Get-ProfileLoadUnloadInfo
{
    param(
        [Parameter(Mandatory=$true, ValueFromPipeline=$true)][String] $Name,
        [int] $CleanUpDays
    )

    BEGIN {}

    PROCESS{
        $SaveErrorActionPreference = $ErrorActionPreference
        $ErrorActionPreference = "SilentlyContinue"
        $date0 = [datetime]::FromFileTime(0)

        $profilelistsidkey = "HKLM:\SOFTWARE\Microsoft\Windows NT\CurrentVersion\ProfileList\$Name"
        $localprofileloadtimelow = 0
        $localprofileloadtimelow = Get-ItemPropertyValue -Path $profilelistsidkey -Name LocalProfileLoadTimeLow
        $localprofileloadtimehigh = 0
        $localprofileloadtimehigh = Get-ItemPropertyValue -Path $profilelistsidkey -Name LocalProfileLoadTimeHigh
        $localprofileloadtime = ConvertToDate $localprofileloadtimelow $localprofileloadtimehigh

        $localprofileunloadtimelow = 0
        $localprofileunloadtimelow = Get-ItemPropertyValue -Path $profilelistsidkey -Name LocalProfileUnLoadTimeLow
        $localprofileunloadtimehigh = 0
        $localprofileunloadtimehigh = Get-ItemPropertyValue -Path $profilelistsidkey -Name LocalProfileUnLoadTimeHigh
        $localprofileunloadtime = ConvertToDate $localprofileunloadtimelow $localprofileunloadtimehigh

        $localprofilecleanupchecktimelow = 0
        $localprofilecleanupchecktimelow = Get-ItemPropertyValue -Path $profilelistsidkey -Name LocalProfileCleanupCheckTimeLow
        $localprofilecleanupchecktimehigh = 0
        $localprofilecleanupchecktimehigh = Get-ItemPropertyValue -Path $profilelistsidkey -Name LocalProfileCleanupCheckTimeHigh
        $localprofilecleanupchecktime = ConvertToDate $localprofilecleanupchecktimelow $localprofilecleanupchecktimehigh

        $profilepath = "-"
        $profilepath = Get-ItemPropertyValue -Path $profilelistsidkey -Name ProfileImagePath
        $manprofilepath = $profilepath + "\NTUSER.MAN"
        $datprofilepath = $profilepath + "\NTUSER.DAT"
        $ntusermodified = $date0
        if( Test-Path $manprofilepath ){
            $ntusermodified = Get-ItemPropertyValue $manprofilepath -Name LastWriteTime
        }
        elseif( Test-Path $datprofilepath ){
            $ntusermodified = Get-ItemPropertyValue $datprofilepath -Name LastWriteTime
        }

        $ErrorActionPreference = $SaveErrorActionPreference

        $determinedfrom = "NtUserDate"
        $basedate = $ntusermodified
        switch( ($localprofileloadtime, $localprofileunloadtime, $localprofilecleanupchecktime | Measure-Object -Maximum).Maximum )
        {
            $date0 
                {
                    break
                }
            #$localprofileloadtime 
            #{
            #    $determinedfrom = "-" # shouldn't happen since would most likely indicate profile currently loaded or machine crashed
            #    $basedate = $date0
            #}
            $localprofileunloadtime 
                {
                    $determinedfrom = "UnloadDate"
                    $basedate = $localprofileunloadtime
                }
            $localprofilecleanupchecktime 
                {
                    $determinedfrom = "CleanupCheckDate"
                    $basedate = $localprofilecleanupchecktime
                }
        }

        $profileagedays = "?"
        if( ($basedate -gt $date0) )
        {
            $profileagedays = [Math]::Truncate( (New-TimeSpan -Start $basedate -End (Get-Date)).TotalDays )
        }

        if( ($cleanupdays -gt 0) -and ($basedate -gt $date0) )
        {
            $cleanupdate = $basedate.AddDays($cleanupdays)
        }
        else 
        {
            $cleanupdate = $date0
        }

        [PSCustomObject] @{
            Sid = $Name
            ProfilePath = $profilepath
            LoadDate = $localprofileloadtime
            UnLoadDate = $localprofileunloadtime
            CleanupCheckDate = $localprofilecleanupchecktime
            NTUserDate = $ntusermodified
            DeterminedFrom = $determinedfrom
            ProfileAgeDays = $profileagedays
            CleanupDate = $cleanupdate
        }
    }

    END{}
}

$SaveErrorActionPreference = $ErrorActionPreference
$ErrorActionPreference = "SilentlyContinue"

# Begin: Check GPO or WMI controlled and get CleanupProfiles value
$WMIcontrolled = $false
$cleanupvalue = 0
$UserStateRoaming = 0
$UserStateRoaming = Get-ItemPropertyValue -Path "HKLM:SOFTWARE\Microsoft\Windows\CurrentVersion\UserState\UserStateTechnologies\ConfigurationControls" -Name RoamingUserProfile
if( ($UserStateRoaming -eq $null) -or ($UserStateRoaming -eq 0) )
{
    # Profiles controlled by GPO, get GPO configured setting if available
    $cleanupvalue = Get-ItemPropertyValue -Path "HKLM:Software\Policies\Microsoft\Windows\System" -Name CleanupProfiles
}
else
{
    # Profiles controlled by WMI, get setting if configured
    $cleanupvalue = Get-ItemPropertyValue -Path "HKLM:Software\Microsoft\Windows\CurrentVersion\UserState\RoamingUserProfile" -Name CleanupProfiles
    $WMIcontrolled = $true
}
if( $cleanupvalue -eq $null )
{
    $cleanupvalue = 0
}
$cleanupwarning = ""
if( $cleanupvalue -eq 0)
{
    $cleanupwarning = " - Value needs to be 1 or larger for profiles to age and be deleted.  Check setting and GP application."
}
# End: Check GPO or  WMI controlled and get CleanupProfiles value

$ErrorActionPreference = $SaveErrorActionPreference

# Get unloaded profiles information on machine
$profinfo = (gwmi win32_userprofile -Filter "Loaded = 'False' and Special = 'False'").sid | Get-ProfileLoadUnloadInfo -CleanUpDays $cleanupvalue | Sort-Object -Property @{E="CleanupDate"; Descending = $false}, @{E="ProfileAgeDays"; Descending = $true}

$Date0 = [datetime]::FromFileTime(0)

"Current Date........: $((Get-Date).ToString())"
"Run By..............: $($env:USERDOMAIN)\$($env:USERNAME)"
$OSInfo = Get-ComputerInfo CsName,OsName,WindowsVersion,OsVersion,OsLastBootUpTime,OsUptime
"Machine Name........: " + $OSInfo.CsName
"Operating System....: " + $OSInfo.OsName
"Windows Version.....: " + $OSInfo.WindowsVersion + " (" + $OSInfo.OsVersion + ")"
$ProfsvcdllVersionInfo = (Get-Item $env:windir\system32\profsvc.dll).VersionInfo
"Profsvc.dll Version.: $($ProfsvcdllVersionInfo.FileMajorPart).$($ProfsvcdllVersionInfo.FileMinorPart).$($ProfsvcdllVersionInfo.FileBuildPart).$($ProfsvcdllVersionInfo.FilePrivatePart)" 
"Last boot time......: " + $OSInfo.OsLastBootUpTime.ToString() + " (Up time: " + $OSInfo.OsUptime + ")"
"-" * 21
"Profile Cleanup Days: $cleanupvalue$cleanupwarning"
"Controlled by WMI...: $WMIcontrolled"
"Profile count.......: $($profinfo.count)"

$profoutput = $profinfo | Select-Object `
    Sid, `
    @{L="User"; E={TranslateSID2Name $_.Sid }}, `
    ProfilePath, `
    @{L="LoadDate"; E={if($_.LoadDate -gt $Date0){ $_.LoadDate } else {"-"}}}, `
    @{L="UnLoadDate"; E={if( $_.UnLoadDate -gt $Date0 ){ $_.UnLoadDate } else {"-"}}}, `
    @{L="CleanupCheckDate"; E={if( $_.CleanupCheckDate -gt $Date0 ){ $_.CleanupCheckDate } else {"-"}}}, `
    @{L="NtUserDate"; E={if( $_.NtUserDate -gt $Date0 ) { $_.NtUserDate } else { "-" }}}, `
    DeterminedFrom, `
    ProfileAgeDays, `
    @{L="CleanupDate"; E={if( $_.CleanupDate -gt $Date0 ) { $_.CleanupDate } else { "-" }}}

# Different output options
#$profoutput | fl *
$profoutput | ft *       # NOTE: may not give all columns depending on window width.
#$profoutput | Out-GridView
#$profoutput | Export-Csv -Path ProfileAge.csv -NoTypeInformation

示例输出

下面是脚本的示例输出。 可以根据窗口的宽度截断表格输出,因此信息的格式可以根据需要更改为其他可用格式:

Current Date........: 8/21/2024
Run As..............: DOMAIN\username
Machine Name........: COMPUTERNAME
Operating System....: Microsoft Windows 10
Windows Version.....: <version>
Profsvc.dll Version.: <version of profsvc.dll>
Last boot time......: <uptime of the machine>
---------------------
Profile Cleanup Days: 30
Controlled by WMI...: False
Profile count.......: 

Sid                                              User               ProfilePath           LoadDate            UnLoadDate          CleanupCheckDate NtUserDate          DeterminedFrom ProfileAgeDays
---                                              ----               -----------           --------            ----------          ---------------- ----------          -------------- -------------
S-1-5-21-xxxxxxxxxx-xxxxxxxxxx-xxxxxxxxx-xxx     DOMAIN\username    C:\Users\username     11.07.2024 13:19:07 11.07.2024 13:20:11 -                11.07.2024 13:20:11 UnloadDate                61

资料来源与适用范围

资料来源
微软官方中文故障文档
适用范围
适用于: Windows 10 版本 1809、Windows 11、Windows Server 2019 和更高版本的 Windows
内容语言
中文;命令、路径和错误标识保留技术原文
本地收录日期
2026-10-26
授权说明
CC BY 4.0

正文与所需资源由本站本地存储。查看来源及更新记录 ↗

请按适用版本和实际日志确认原因;本站没有对每一种系统或设备逐项执行文中的操作。