Remove-WmiObject - 删除用户配置文件

Remove-WmiObject - Delete User Profiles

这是使用以下 constraints/rules 远程删除用户配置文件的代码:

########## List of accounts/Student profiles older than 21 days and not test accounts to be deleted  #######################



foreach ($computer in (Get-Content e:\cleanupscript\scripts\ComputerList.csv)) {


if(Test-Connection -ComputerName $computer -count 1){
    $userfolders = Get-ChildItem "\$computer\C$\users\"  | Select-Object -ExpandProperty Name
}


#The list of accounts, which profiles must not be deleted
$ExcludedUsers ="Public","administrator","csimg",”DefaultAppPool”, "ksnproxy", "test1","test2","test3","test4","test5","test6","test7","test8","test9","test10","test11","test12","test13","test14","test15","test16","test17","test18","test19","test20","test21","test22","test23","test24","test25","test26","test27","test28","test29","test30","test31","test32","test33","test34","test35","test36","test37","test38","test39","test40","test41","test42","test43","test44","test45","test46","test47","test48","test49","test50","test51","test52","test53","test54","test55","test56","test57","test58","test59","test60","test61","test62","test63","test64","test65","test66","test67","test68","test69","test70","test71","test72","test73","test74","test75","test76","test77","test78","test79","test80","test81","test82","test83","test84","test85"



        $StudentsProfiles = Get-WmiObject -ComputerName $computer -Class Win32_UserProfile | 
            Select-Object   PSComputerName,
                            Sid, 
                            LocalPath, 
                            @{Label='LastUseTime';Expression={$_.ConvertToDateTime($_.LastUseTime)} } |
                        
            
            Where-Object -FilterScript {![System.String]::IsNullOrWhiteSpace($_.LastUseTime)} |
            Where-Object -FilterScript {!($_.LocalPath -eq "C:\Windows\ServiceProfiles\ksnproxy")} |
            Where-Object -FilterScript {!($ExcludedUsers -like ($_.LocalPath.Replace("C:\Users\","")))} |
            Sort-Object -Property {($_.LastUseTime)} |
            Select-Object -First 3 |
         

foreach ($StudentsProfile in $StudentsProfiles)
{

    #Write-Host $StudentsProfile.LocalPath, $computer,  $StudentsProfile.LastUseTime,  "profile existing” -ForegroundColor Red

    
    if (!($ExcludedUsers -like ($StudentsProfile.LocalPath.Replace("C:\Users\",""))))
    {     
        $StudentsProfile | Remove-WmiObject 
        Write-Host $computer, $StudentsProfile.LocalPath, $StudentsProfile.LastUseTime,  "profile deleted” -ForegroundColor Magenta
    }
          
}

}

Remove-WmiObject:输入对象不能绑定到命令的任何参数,因为命令不接受管道输入或 输入及其属性与采用管道输入的任何参数都不匹配。 在 line:1 char:7

顺便说一句:CIM cmdlet(例如,Get-CimInstance) superseded the WMI cmdlets (e.g., Get-WmiObject) in PowerShell v3 (released in September 2012). Therefore, the WMI cmdlets should be avoided, not least because PowerShell (Core) (v6+), where all future effort will go, doesn't even have them anymore. Note that WMI still underlies the CIM cmdlets, however. For more information, see this answer.

  • Remove-WmiObject receives input from the pipeline, it expects input objects of type System.Management.ManagementObject时,绑定到它的-InputObject参数。

  • 相比之下,您的 $StudentsProfiles 变量 包含此类型的对象,因为您已应用 Select-Object with 属性 names 到原始 Get-WmiObject 调用,它创建通用类型的对象,[pscustomobject],即 与输入对象的类型,并且只包含指定的属性,其值是从输入对象的同名属性中复制的。

因此,将集合 $StudentsProfiles 中的对象传送到 Remove-WmiObject 会导致您看到的错误:输入对象的类型错误。


解决方案:

省略 Select-Object PSComputerName, ... 调用并将管道限制为仅 过滤 Where-Object 调用,Select-Object 调用 -Last) 和 sorting 命令,它们都不会改变输入对象的身份:

使用流水线的简化版本:

$StudentsProfiles = Get-WmiObject -ComputerName $computer -Class Win32_UserProfile | 
  Where-Object -FilterScript {
    $_.LastUseTime -and 
      $_.LocalPath -ne "C:\Windows\ServiceProfiles\ksnproxy" -and
        (Split-Path -Leaf $_.LocalPath) -notin $ExcludedUsers
  } |
    Sort-Object LastUseTime |
      Select-Object -First 3

注意:$_.ConvertToDateTime($_.LastUseTime) - 即显式转换为 [datetime] - 实际上并不需要:

  • 要测试值是否为非空(非空),$_.LastUseTime——这是一个代表时间戳的字符串,可以按原样使用,因为将 $null''(空字符串)解释为布尔值会导致 $false,而任何 nonempty 字符串会产生 $true.

  • 类似地,LastUseTime 可以传递给 Sort-Object 以按此 属性 值 直接 排序,因为时间戳的字符串表示 - 例如'20211110143544.500000-300' - 以 词法 排序等同于 时间 排序的方式构建。

顺便说一句:首选 CIM cmdlet 在这方面优于 WMI cmdlet:它们将时间戳 直接 表示为 [datetime] - 无需转换。