脚本没有正确地将WMI对象分配给阵列
我试图创建一个脚本来检测长达15天的域用户配置文件并删除它们。这将捆绑在一个工作中,在运行之前将会注销任何闲置会话。脚本没有正确地将WMI对象分配给阵列
我知道这通常是通过GPO完成的,但是由于各种原因它不适合用于这个特定业务领域。
这里是我的代码:
#Assign how old the user profile must be for deletion
[int]$NoOfDays = 15
#Get WMI object where it is a domain account and over 15 days old
$Objects = @(Get-WmiObject -Class Win32_UserProfile | Where {
(!$_.Special) -and
$_.ConvertToDateTime($_.LastUseTime) -lt (Get-Date).AddDays(-15)
})
if ($Objects -eq $null) {
#If no users returned, write to host.
Write-Host "no profiles found for deletion"
} else {
#If users are found, do the following
foreach ($Object in $Objects) {
Write-Host "'$($object.LocalPath)' has been identified for deletion"
}
foreach ($Object in $Objects) {
try {
Write-Host "Attempting to delete profile '$($Object.LocalPath)'"
Remove-WmiObject
Write-Host "Deleted profile '$($Object.LocalPath)' successfully."
} catch {
Write-Host "Unable to delete profile '$($Object.LocalPath)'" -ErrorAction Continue
}
}
}
没有输出,它只是返回命令没有错误行,立竿见影。
我试图注释掉删除配置文件的位,在每个语句的第一个语句之后结束else,看看删除了哪些内容,但它没有起作用。
$Objects = @(...)
确保$Objects
是一个数组,即使该命令没有返回结果。一个数组(甚至是一个空数组)永远不会等于$null
,所以你的第一个条件永远不会被触发。
变化
if ($Objects -eq $null) {
到
if ($Objects.Count -gt 0) {
和代码应该做你的期望。
或者Ansgar's solution您可以避免将$Objects
变量分配给数组(看不出为什么需要这样)。
$Objects = Get-WmiObject -Class Win32_UserProfile | Where {
(!$_.Special) -and
$_.ConvertToDateTime($_.LastUseTime) -lt (Get-Date).AddDays(-15)
}
-eq $null
然后可以使用检查。您也可能会发现[string]::IsNullOrEmpty($Object)
有用,因为这将检测到一个空阵列。
你提到没有输出......这是怀疑,因为你应该得到Write-Hosts
印刷东西。在我的机器上,我得到了一个错误$_.ConvertToDateTime
...我建议在控制台的一条平行线上运行你的代码,以确保它符合你的期望。
无法为此代码获取WMI解决的日期时间问题,但是我的本地脚本副本存在问题。 –
好吧,事实证明这是一个问题的组合。主要的是它运行的PS版本,不能在4上工作。下一阶段是尝试强制PowerShell将其作为版本3运行。如前所述,它不需要在数组中处理。这是我的最终脚本(不喜欢每状态后返回所以离开原来的格式):
if ($PSVersionTable.PSVersion.Major -eq 4)
{
Write-host "this script will terminate as machine is running PowerShell version 4"
exit 1
}
Else
{
Start-Sleep -s 5
Set-Location -Path C:\Users
#Assign how old the user profile must be for deletion
[DateTime]$AdjustedDate = (Get-Date).AddDays(-15)
[DateTime]$CompareDate = Get-Date $AdjustedDate -Format MM-dd-yyyy
$Hostname = $env:computername
#$testdate = Get-WmiObject -Class Win32_UserProfile | select {$_.ConvertToDateTime($_.lastusetime).ToShortDateString()}
#write-host $testdate
#Get WMI object where it is a domain account and over 15 days old
$Objects = Get-WmiObject -Class Win32_UserProfile | Where {(!$_.Special) -and ($_.ConvertToDateTime($_.lastusetime) -lt (Get-Date).AddDays(-15)) -and $_.LocalPath -notlike "*.NET*" -and $_.LocalPath -notlike "*SQL*" -and $_.LocalPath -notlike "*Admin*" -and $_.LocalPath -notlike "*ADMIN*"}
#If no users returned, write to host.
If($Objects.Count -eq 0)
{
Write-host "no profiles found for deletion"
}
#If users are found, do the following
Else
{
Foreach($Object in $Objects)
{
Write-host "'$($object.LocalPath)' has been identified for deletion"
Write-host " "
}
Foreach($Object in $Objects)
{
Try{
Write-Host "Attempting to delete profile '$($Object.LocalPath)'"
$UserSID = (Get-WmiObject Win32_UserProfile | Where {$_.LocalPath -like '$($object.LocalPath)'}).SID
Remove-WmiObject -InputObject $Object
Write-Host "Deleted profile '$($Object.LocalPath)' successfully."
}
Catch{
Write-Host "Unable to delete profile '$($Object.LocalPath)' due to the following error"
Write-Host "$error" -ErrorAction Continue
}
}
}
}
它似乎对删除-WmiObject可以cmdlet的一个部分的输入参数在上面的代码中给定的被错过。 –
@Andrei Odegov对不起,谢谢你指出。我设法使删除工作正常。 –