【问题标题】:Remove-WmiObject - Delete User ProfilesRemove-WmiObject - 删除用户配置文件
【发布时间】:2021-12-31 01:04:56
【问题描述】:

这是远程删除用户配置文件的代码,具有以下约束/规则:

########## 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 : 输入对象不能绑定到命令的任何参数,因为命令不接受管道输入或 input 及其属性与任何接受管道输入的参数都不匹配。 在 line:1 char:7

  • $st | Remove-WmiObject -Authentication Connect
  •   ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    
    • CategoryInfo : InvalidArgument: (@{PSComputerNam...-07 6:49:46 AM}:PSObject) [Remove-WmiObject], ParameterBindingException
    • FullyQualifiedErrorId : InputObjectNotBound,Microsoft.PowerShell.Commands.RemoveWmiObject

【问题讨论】:

    标签: powershell wmi script user-profile wmi-query


    【解决方案1】:

    顺便说一句:CIM cmdlet(例如,Get-CimInstance)取代了 PowerShell v3(2012 年 9 月发布)中的 WMI cmdlet(例如,Get-WmiObject)。因此,应该避免使用 WMI cmdlet,尤其是因为 PowerShell (Core) (v6+),未来的所有努力都将用于,甚至不再拥有它们。但是请注意,WMI 仍然是 CIM cmdlet 的基础。如需更多信息,请参阅this answer

    • Remove-WmiObject 接收到来自管道的输入 时,它需要System.Management.ManagementObject 类型的输入对象,该对象绑定到它的-InputObject 参数。

    • 相比之下,您的 $StudentsProfiles 变量确实包含此类型的对象,因为您已将 Select-Object 与属性名称应用于原始 Get-WmiObject调用,它创建通用类型的对象,[pscustomobject],它与输入对象的类型无关,并且只包含具有从输入对象的相同属性复制的值的指定属性名字。

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


    解决方案

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

    使用流水线的简化版本:

    $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,而任何非空字符串产生$true

    • 同样,LastUseTime 可以传递给Sort-Object直接按此属性值排序,因为时间戳的字符串表示形式 - 例如'20211110143544.500000-300' - 以 lexical 排序等同于 chronological 排序的方式构造。

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

    【讨论】:

    • 非常感谢您提供的有用信息。正如您在评论中提到的,我已经得到了解决方案。
    • 很高兴听到这个消息,@RodrigoNM;我的荣幸。
    • @RodrigoNM,可以进一步简化解决方案 - 请参阅我的更新。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-05-26
    相关资源
    最近更新 更多