2017-07-18 74 views
1

我试图创建一个脚本来检测长达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,看看删除了哪些内容,但它没有起作用。

+0

它似乎对删除-WmiObject可以cmdlet的一个部分的输入参数在上面的代码中给定的被错过。 –

+0

@Andrei Odegov对不起,谢谢你指出。我设法使删除工作正常。 –

回答

2

$Objects = @(...)确保$Objects是一个数组,即使该命令没有返回结果。一个数组(甚至是一个空数组)永远不会等于$null,所以你的第一个条件永远不会被触发。

变化

if ($Objects -eq $null) { 

if ($Objects.Count -gt 0) { 

和代码应该做你的期望。

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 ...我建议在控制台的一条平行线上运行你的代码,以确保它符合你的期望。

+0

无法为此代码获取WMI解决的日期时间问题,但是我的本地脚本副本存在问题。 –

0

好吧,事实证明这是一个问题的组合。主要的是它运行的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 
          } 

      }  
     } 
}