根据 Appdata\Local 文件夹的日期删除用户配置文件
Delete user profiles based on the date of the Appdata\Local folder
感谢 Microsoft 打破了“在系统重新启动时删除早于指定天数的用户配置文件”GPO 并且这些年来都没有修复它,我需要一个脚本来删除旧的用户配置文件。问题是,我不需要它查找用户配置文件文件夹本身的修改日期,而是根据用户配置文件的 Appdata 文件夹中本地文件夹的修改日期删除用户配置文件。我注意到,即使您每天登录,用户个人资料文件夹的修改日期可能多年都不会改变,但本地文件夹似乎确实会根据您的登录时间而改变。
所以,我从用户 cxr-aus 制作的 spiceworks post 中抓取了这个。
$useraccounts = Get-ChildItem -path C:\users\ | Where-Object lastwritetime -lt (Get-Date).AddDays(90) | Select-Object Name
$sort = $useraccounts | ForEach-Object {$_.Name}
$removeaccounts = $sort -join "|"
Get-WmiObject -Class Win32_userprofile | Where-Object {($_.LocalPath -match "$removeaccounts") -and (!$_.special)} | Remove-WmiObject -whatif
您可以删除代码末尾的 -whatif 以使其删除用户配置文件。
我 运行 遇到的第一个问题是我需要这个来删除多个用户配置文件,因此 Remove-WmiObject 不起作用,因为 Get-WmiObject return 对我来说有多个配置文件,所以要修复它为了工作,我使用 % { $_.Delete()} 而不是像下面这样。
警告:请谨慎使用以下代码,因为 -whatif 不适用于它,它可能会开始从您的计算机上删除多个配置文件。
$useraccounts = Get-ChildItem -path C:\users\ | Where-Object {$_.lastwritetime -lt (Get-Date).AddDays(90)} | Select-Object Name
Foreach ( $user in $useraccounts) {
$sort = $useraccounts | ForEach-Object {$_.Name}
$removeaccounts = $sort -join "|"
$Username = $removeaccounts.name
Get-WmiObject -Class Win32_userprofile | Where-Object {($_.LocalPath -match "$Username") -and (!$_.special)} | % { $_.Delete()}}
您可以看到我确实更改了代码的其他一些方面以尝试将其分解,以便代码一次在一个配置文件上运行。这种方法有效,因为它将根据用户配置文件文件夹的修改日期开始删除文件夹
但问题是它会删除昨天可能已经使用过的用户配置文件,但是用户配置文件文件夹的修改日期没有改变。
所以我需要脚本做的是:
1.Get C:\users 目录中的所有用户配置文件文件夹
- 进入用户配置文件文件夹并获取 appdata\local 文件夹的修改日期。
3.Then return 只有 appdata\local 文件夹在这种情况下 90 天未被修改的用户配置文件文件夹。
我已经尝试了一些方法来改变这段似乎是死胡同的代码。有人可以帮我解决这个问题吗?
好的。
确保在生产中使用之前彻底测试它。
我添加了一些有用的注释来破译您在这段代码中尝试做的事情。
$VerbosePreference = 'Continue'
## getting the name of the users
## this returns the filtered results below
$useraccounts = Get-ChildItem -Path $env:HOMEDRIVE\users\ | Where-Object lastwritetime -LT (Get-Date).AddDays(90)
## $useraccounts returns
<#
Directory: /Users
UnixMode User Group LastWriteTime Size Name
-------- ---- ----- ------------- ---- ----
drwxr-x--- jacoby staff 5/2/2022 19:04 1056 jacoby
drwxrwxrwt root wheel 3/26/2022 00:21 128 Shared
#>
## $useraccounts.name returns
<#
PS > $useraccounts.name
jacoby
Shared
#>
## if we use get-childitem | get-member we can see that we have access to a lot of
## properties returned like the .name value
#### we don't need any of this
####$sort = $useraccounts | ForEach-Object {$_.Name}
#####$removeaccounts = $sort -join '|'
## ok let's do something here
## for each account in my list
foreach ($account in $useraccounts) {
## let's write some info so we know what's happening
Write-Verbose -Message ('currently working with {0}' -f $account)
## we want to check moditfication time of folder so we gotta see if it exists
## we want to test c:\users\ the current account \ appdata\local
## $account.FullName gives us c:\users\accountname so we just need to add the rest
$testpath1 = $account.FullName + '\appdata\local'
Write-Verbose -Message ('we generated the path {0}' -f $testpath1)
## imma give you some error checking
## this is ugly because it could be there but we can't access it
if ((Test-Path -Path $testpath1 -ErrorAction SilentlyContinue) -eq $true) {
## if the path exists here's what we'll do
## get a count of all the file modified in the last 90 days
$count = (Get-ChildItem -Path $testpath1 `
## -Recurse
## uncomment this if you want recurse or depth
| Where-Object {
$_.LastWriteTime -gt (Get-Date).AddDays(-90)
}
).Count
## now that we have a count we can test if the count is less than than 1 (0)
## that means no files in these folder were modified in the last 90 days
if ($count -lt 1) {
####
##
## this is the area where we can take action on the
## folders/files that have not been modified in the
## last 90 days
## you might delete them or just log them somewbere
##
####
Write-Verbose -Message 'no file modified in the last 90 days'
####
## this is your original deletion pipeline
##Get-WmiObject -Class Win32_userprofile | Where-Object {($_.LocalPath -match "$account") -and (!$_.special)} | Remove-WmiObject -whatif
##i have not tested this. be careful.
####
}
else {
Write-Verbose -Message ('{0} files have been modified in the last 90 days! We do not want delete this.' -f $count)
####
##
## these is the area where we can take action if the
## files/folder HAVE been modified recently
## we would NOT want to delete these files
##
####
}
}
## do some stuff before ending the for each loop
## maybe write our changes somewhere permanent
}
再次感谢“又一个鼠标受害者”对脚本的帮助。我已针对我的环境稍微更改了脚本
$VerbosePreference = 'Continue'
$ExcludedUsers="Public","default","defaultuser0","public","administrator"
$path = "$Env:SystemDrive\users"
## getting the name of the users
## this returns the filtered results below
$useraccounts = Get-ChildItem -Path $path -Exclude $ExcludedUsers | Where-Object {$_.lastwritetime -lt (Get-Date).AddDays(-30)}
## $useraccounts returns
<#
Directory: /Users
UnixMode User Group LastWriteTime Size Name
-------- ---- ----- ------------- ---- ----
drwxr-x--- jacoby staff 5/2/2022 19:04 1056 jacoby
drwxrwxrwt root wheel 3/26/2022 00:21 128 Shared
#>
## $useraccounts.name returns
<#
PS > $useraccounts.name
jacoby
Shared
#>
## if we use get-childitem | get-member we can see that we have access to a lot of
## properties returned like the .name value
#### we don't need any of this
####$sort = $useraccounts | ForEach-Object {$_.Name}
#####$removeaccounts = $sort -join '|'
## ok let's do something here
## for each account in my list
foreach ($account in $useraccounts)
{
## let's write some info so we know what's happening
Write-Verbose -Message ('currently working with {0}' -f $account)
## we want to check moditfication time of folder so we gotta see if it exists
## we want to test c:\users\ the current account \ appdata\local
## $account.FullName gives us c:\users\accountname so we just need to add the rest
$testpath1 = $account.FullName + '\appdata\local'
Write-Verbose -Message ('we generated the path {0}' -f $testpath1)
## imma give you some error checking
## this is ugly because it could be there but we can't access it
if ((Test-Path -Path $testpath1 -ErrorAction SilentlyContinue) -eq $true)
{
## if the path exists here's what we'll do
## get a count of all the file modified in the last 30 days
$count = (Get-ChildItem -Path $testpath1 | Where-Object { $_.LastWriteTime -gt (Get-Date).AddDays(-30) }).Count
## now that we have a count we can test if the count is less than than 1 (0)
## that means no files in these folders were modified in the last 30 days
if ($count -lt 1) {
####
##
## this is the area where we can take action on the
## folders/files that have not been modified in the
## last 30 days
## you might delete them or just log them somewbere
##
####
Write-Verbose -Message 'no file modified in the last 30 days'
####
## this is your original deletion pipeline
#Get-WmiObject -Class Win32_userprofile | Where-Object {($_.LocalPath -contains "$account") -and (!$_.special)} | Remove-WmiObject -whatif
##i have not tested this. be careful.
####
}
else {
Write-Verbose -Message ('{0} files have been modified in the last 30 days! We do not want delete this.' -f $count)
####
##
## these is the area where we can take action if the
## files/folder HAVE been modified recently
## we would NOT want to delete these files
##
####
}
}
## do some stuff before ending the for each loop
## maybe write our changes somewhere permanent
}
我首先将 $env:HomeDrive 更改为 $env:SystemDrive 因为我的环境设置不同。我还添加了一个 $ExcludeUsers,这样它就不会获取管理员或其他系统用户配置文件文件夹。由于您所做的更改,Remove-WmiObject 适用于 Users 文件夹中的多个配置文件,并且我能够通过 运行 此脚本一次删除 20 多个配置文件。出于某种原因,我想不通,-match 不再有效。它不会将 $account 视为完整的本地路径,因此我将其更改为 -contains,这对我来说似乎已经足够了。对于其他人,请务必在使用前彻底测试脚本。这是一个非常强大的脚本。
感谢 Microsoft 打破了“在系统重新启动时删除早于指定天数的用户配置文件”GPO 并且这些年来都没有修复它,我需要一个脚本来删除旧的用户配置文件。问题是,我不需要它查找用户配置文件文件夹本身的修改日期,而是根据用户配置文件的 Appdata 文件夹中本地文件夹的修改日期删除用户配置文件。我注意到,即使您每天登录,用户个人资料文件夹的修改日期可能多年都不会改变,但本地文件夹似乎确实会根据您的登录时间而改变。
所以,我从用户 cxr-aus 制作的 spiceworks post 中抓取了这个。
$useraccounts = Get-ChildItem -path C:\users\ | Where-Object lastwritetime -lt (Get-Date).AddDays(90) | Select-Object Name
$sort = $useraccounts | ForEach-Object {$_.Name}
$removeaccounts = $sort -join "|"
Get-WmiObject -Class Win32_userprofile | Where-Object {($_.LocalPath -match "$removeaccounts") -and (!$_.special)} | Remove-WmiObject -whatif
您可以删除代码末尾的 -whatif 以使其删除用户配置文件。 我 运行 遇到的第一个问题是我需要这个来删除多个用户配置文件,因此 Remove-WmiObject 不起作用,因为 Get-WmiObject return 对我来说有多个配置文件,所以要修复它为了工作,我使用 % { $_.Delete()} 而不是像下面这样。
警告:请谨慎使用以下代码,因为 -whatif 不适用于它,它可能会开始从您的计算机上删除多个配置文件。
$useraccounts = Get-ChildItem -path C:\users\ | Where-Object {$_.lastwritetime -lt (Get-Date).AddDays(90)} | Select-Object Name
Foreach ( $user in $useraccounts) {
$sort = $useraccounts | ForEach-Object {$_.Name}
$removeaccounts = $sort -join "|"
$Username = $removeaccounts.name
Get-WmiObject -Class Win32_userprofile | Where-Object {($_.LocalPath -match "$Username") -and (!$_.special)} | % { $_.Delete()}}
您可以看到我确实更改了代码的其他一些方面以尝试将其分解,以便代码一次在一个配置文件上运行。这种方法有效,因为它将根据用户配置文件文件夹的修改日期开始删除文件夹 但问题是它会删除昨天可能已经使用过的用户配置文件,但是用户配置文件文件夹的修改日期没有改变。 所以我需要脚本做的是:
1.Get C:\users 目录中的所有用户配置文件文件夹
- 进入用户配置文件文件夹并获取 appdata\local 文件夹的修改日期。
3.Then return 只有 appdata\local 文件夹在这种情况下 90 天未被修改的用户配置文件文件夹。
我已经尝试了一些方法来改变这段似乎是死胡同的代码。有人可以帮我解决这个问题吗?
好的。
确保在生产中使用之前彻底测试它。
我添加了一些有用的注释来破译您在这段代码中尝试做的事情。
$VerbosePreference = 'Continue'
## getting the name of the users
## this returns the filtered results below
$useraccounts = Get-ChildItem -Path $env:HOMEDRIVE\users\ | Where-Object lastwritetime -LT (Get-Date).AddDays(90)
## $useraccounts returns
<#
Directory: /Users
UnixMode User Group LastWriteTime Size Name
-------- ---- ----- ------------- ---- ----
drwxr-x--- jacoby staff 5/2/2022 19:04 1056 jacoby
drwxrwxrwt root wheel 3/26/2022 00:21 128 Shared
#>
## $useraccounts.name returns
<#
PS > $useraccounts.name
jacoby
Shared
#>
## if we use get-childitem | get-member we can see that we have access to a lot of
## properties returned like the .name value
#### we don't need any of this
####$sort = $useraccounts | ForEach-Object {$_.Name}
#####$removeaccounts = $sort -join '|'
## ok let's do something here
## for each account in my list
foreach ($account in $useraccounts) {
## let's write some info so we know what's happening
Write-Verbose -Message ('currently working with {0}' -f $account)
## we want to check moditfication time of folder so we gotta see if it exists
## we want to test c:\users\ the current account \ appdata\local
## $account.FullName gives us c:\users\accountname so we just need to add the rest
$testpath1 = $account.FullName + '\appdata\local'
Write-Verbose -Message ('we generated the path {0}' -f $testpath1)
## imma give you some error checking
## this is ugly because it could be there but we can't access it
if ((Test-Path -Path $testpath1 -ErrorAction SilentlyContinue) -eq $true) {
## if the path exists here's what we'll do
## get a count of all the file modified in the last 90 days
$count = (Get-ChildItem -Path $testpath1 `
## -Recurse
## uncomment this if you want recurse or depth
| Where-Object {
$_.LastWriteTime -gt (Get-Date).AddDays(-90)
}
).Count
## now that we have a count we can test if the count is less than than 1 (0)
## that means no files in these folder were modified in the last 90 days
if ($count -lt 1) {
####
##
## this is the area where we can take action on the
## folders/files that have not been modified in the
## last 90 days
## you might delete them or just log them somewbere
##
####
Write-Verbose -Message 'no file modified in the last 90 days'
####
## this is your original deletion pipeline
##Get-WmiObject -Class Win32_userprofile | Where-Object {($_.LocalPath -match "$account") -and (!$_.special)} | Remove-WmiObject -whatif
##i have not tested this. be careful.
####
}
else {
Write-Verbose -Message ('{0} files have been modified in the last 90 days! We do not want delete this.' -f $count)
####
##
## these is the area where we can take action if the
## files/folder HAVE been modified recently
## we would NOT want to delete these files
##
####
}
}
## do some stuff before ending the for each loop
## maybe write our changes somewhere permanent
}
再次感谢“又一个鼠标受害者”对脚本的帮助。我已针对我的环境稍微更改了脚本
$VerbosePreference = 'Continue'
$ExcludedUsers="Public","default","defaultuser0","public","administrator"
$path = "$Env:SystemDrive\users"
## getting the name of the users
## this returns the filtered results below
$useraccounts = Get-ChildItem -Path $path -Exclude $ExcludedUsers | Where-Object {$_.lastwritetime -lt (Get-Date).AddDays(-30)}
## $useraccounts returns
<#
Directory: /Users
UnixMode User Group LastWriteTime Size Name
-------- ---- ----- ------------- ---- ----
drwxr-x--- jacoby staff 5/2/2022 19:04 1056 jacoby
drwxrwxrwt root wheel 3/26/2022 00:21 128 Shared
#>
## $useraccounts.name returns
<#
PS > $useraccounts.name
jacoby
Shared
#>
## if we use get-childitem | get-member we can see that we have access to a lot of
## properties returned like the .name value
#### we don't need any of this
####$sort = $useraccounts | ForEach-Object {$_.Name}
#####$removeaccounts = $sort -join '|'
## ok let's do something here
## for each account in my list
foreach ($account in $useraccounts)
{
## let's write some info so we know what's happening
Write-Verbose -Message ('currently working with {0}' -f $account)
## we want to check moditfication time of folder so we gotta see if it exists
## we want to test c:\users\ the current account \ appdata\local
## $account.FullName gives us c:\users\accountname so we just need to add the rest
$testpath1 = $account.FullName + '\appdata\local'
Write-Verbose -Message ('we generated the path {0}' -f $testpath1)
## imma give you some error checking
## this is ugly because it could be there but we can't access it
if ((Test-Path -Path $testpath1 -ErrorAction SilentlyContinue) -eq $true)
{
## if the path exists here's what we'll do
## get a count of all the file modified in the last 30 days
$count = (Get-ChildItem -Path $testpath1 | Where-Object { $_.LastWriteTime -gt (Get-Date).AddDays(-30) }).Count
## now that we have a count we can test if the count is less than than 1 (0)
## that means no files in these folders were modified in the last 30 days
if ($count -lt 1) {
####
##
## this is the area where we can take action on the
## folders/files that have not been modified in the
## last 30 days
## you might delete them or just log them somewbere
##
####
Write-Verbose -Message 'no file modified in the last 30 days'
####
## this is your original deletion pipeline
#Get-WmiObject -Class Win32_userprofile | Where-Object {($_.LocalPath -contains "$account") -and (!$_.special)} | Remove-WmiObject -whatif
##i have not tested this. be careful.
####
}
else {
Write-Verbose -Message ('{0} files have been modified in the last 30 days! We do not want delete this.' -f $count)
####
##
## these is the area where we can take action if the
## files/folder HAVE been modified recently
## we would NOT want to delete these files
##
####
}
}
## do some stuff before ending the for each loop
## maybe write our changes somewhere permanent
}
我首先将 $env:HomeDrive 更改为 $env:SystemDrive 因为我的环境设置不同。我还添加了一个 $ExcludeUsers,这样它就不会获取管理员或其他系统用户配置文件文件夹。由于您所做的更改,Remove-WmiObject 适用于 Users 文件夹中的多个配置文件,并且我能够通过 运行 此脚本一次删除 20 多个配置文件。出于某种原因,我想不通,-match 不再有效。它不会将 $account 视为完整的本地路径,因此我将其更改为 -contains,这对我来说似乎已经足够了。对于其他人,请务必在使用前彻底测试脚本。这是一个非常强大的脚本。