在远程桌面协议(RDP)服务器上,通常会有大量的用户配置文件。这些服务器的C盘空间相对较小,因此用户配置文件对系统性能有显著影响。由于合规性和文档记录的原因,将用户配置文件移动到其他驱动器不是一个可行的选项。幸运的是,这些用户配置文件不包含关键数据,因此定期清理它们不会带来问题。然而,由于服务器数量众多,手动进行清理是不现实的,这就需要使用脚本自动化来解决。
本文将介绍如何编写一个PowerShell脚本来自动化管理RDP服务器上用户配置文件的过程,包括排除特定用户组、处理特殊账户以及使用CIM代替WMI进行操作。
需要编写一个脚本,它满足以下要求:
在深入脚本编写之前,需要了解与Windows交互的方法。虽然可以通过删除配置文件文件夹来删除配置文件,但这不是一个干净的操作,因为它不会清理注册表。因此,需要与Windows本身交互,并请求Windows为删除配置文件,类似于通过控制面板手动操作的方式。
在过去,WMI可能是显而易见的选择。然而,WMI正在被弃用。为了目的,使用CIM,因为有一个非常方便的方式来通过Get-CimObject获取用户配置文件列表,然后通过Remove-CimInstance删除选定的用户配置文件。
脚本由多个部分组成。
在环境中,排除列表包括管理员组作为示例。根据您的需求,您可以添加特定应用程序组,这些组的账户需要持久化用户配置文件。
在脚本的某个阶段,需要评估用户所属的组列表是否不包含排除列表中的组。脚本高手可能能够用一行清晰的代码实现这一点,但为了理智,将这个检查放在一个函数中,以保持脚本的其余部分易于理解。
Import-Module ActiveDirectory
function MemberOfExcludedGroup {
param (
$memberof,
$exclusionlist
)
$retval = $false
$exclusionlist | foreach {
if ($memberof -match $_) {
$retval = $true
}
}
return $retval
}
$exclusionlist = @(
"Domain Admins",
"Administrators"
)
确定哪些用户可能在清理过程的范围内是第一步。使用以下代码段来实现这一点。该代码段用英语表达的意思是“获取指定OU中的所有用户,他们不是排除组成员,并获取他们的SID。”
$userOUpath = (Get-ADOrganizationalUnit -Filter 'Name -like "DeltaV Users"').DistinguishedName
$users = Get-ADUser -Filter * -SearchBase $userOUpath -properties memberof, SID |
where {! (MemberOfExcludedGroup $_.MemberOf $exclusionlist)} |
foreach {
$_.SID.Value
}
现在已经得到了范围内用户的列表,将它与范围内的配置文件进行匹配。
Get-CimInstance win32_userprofile |
where {
$users.Contains($_.SID) -and !$_.Special -and !$_.Loaded
} |
foreach {
"Deleting profile $($_.LocalPath)"
Remove-CimInstance $_
}
将所有这些内容整合在一起,最终的脚本出奇地简单。
Import-Module ActiveDirectory
function MemberOfExcludedGroup {
param (
$memberof,
$exclusionlist
)
$retval = $false
$exclusionlist | foreach {
if ($memberof -match $_) {
$retval = $true
}
}
return $retval
}
$exclusionlist = @(
"Domain Admins",
"Administrators"
)
$userOUpath = (Get-ADOrganizationalUnit -Filter 'Name -like "DeltaV Users"').DistinguishedName
$users = Get-ADUser -Filter * -SearchBase $userOUpath -properties memberof, SID |
where {! (MemberOfExcludedGroup $_.MemberOf $exclusionlist)} |
foreach {
$_.SID.Value
}
Get-CimInstance win32_userprofile |
where {
$users.Contains($_.SID) -and !$_.Special -and !$_.Loaded
} |
foreach {
"Deleting profile $($_.LocalPath)"
Remove-CimInstance $_
}