脚本没有正确地将 WMI 对象分配给数组
Script not assigning WMI objects to array correctly
我正在尝试创建一个脚本来检测最多 15 天的域用户配置文件并将其删除。这将捆绑在一个作业中,该作业将在运行前注销所有空闲会话。
我知道这通常会通过 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
}
}
}
没有输出,直接returns到命令行没有错误。
我试图注释掉删除配置文件的位,在每个语句的第一个之后结束 else 以查看标识为删除的内容,但它没有用。
$Objects = @(...)
确保 $Objects
是一个数组,即使命令没有 return 结果。一个数组(即使是一个空数组)永远不会等于 $null
,所以你的第一个条件永远不会被触发。
改变
if ($Objects -eq $null) {
到
if ($Objects.Count -gt 0) {
并且代码应该符合您的预期。
或者 您可以避免将 $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
错误...我建议 运行 你的代码在控制台中的一行中,以确保它按照你的预期进行。
好的,事实证明这是一个问题的组合。主要的是 PS 版本运行s,在 4 上不起作用。下一阶段是尝试强制 PowerShell 运行 它作为版本 3。如前所述不需要在数组中处理。这是我的最终脚本(不喜欢 returns 在每个和条件之后保持格式不变):
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
}
}
}
}
我正在尝试创建一个脚本来检测最多 15 天的域用户配置文件并将其删除。这将捆绑在一个作业中,该作业将在运行前注销所有空闲会话。
我知道这通常会通过 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
}
}
}
没有输出,直接returns到命令行没有错误。
我试图注释掉删除配置文件的位,在每个语句的第一个之后结束 else 以查看标识为删除的内容,但它没有用。
$Objects = @(...)
确保 $Objects
是一个数组,即使命令没有 return 结果。一个数组(即使是一个空数组)永远不会等于 $null
,所以你的第一个条件永远不会被触发。
改变
if ($Objects -eq $null) {
到
if ($Objects.Count -gt 0) {
并且代码应该符合您的预期。
或者 $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
错误...我建议 运行 你的代码在控制台中的一行中,以确保它按照你的预期进行。
好的,事实证明这是一个问题的组合。主要的是 PS 版本运行s,在 4 上不起作用。下一阶段是尝试强制 PowerShell 运行 它作为版本 3。如前所述不需要在数组中处理。这是我的最终脚本(不喜欢 returns 在每个和条件之后保持格式不变):
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
}
}
}
}