【问题标题】:How do you store a list of users (C:\Users) in PowerShell to use later on in the same script?如何在 PowerShell 中存储用户列表 (C:\Users) 以便稍后在同一脚本中使用?
【发布时间】:2021-06-14 15:13:24
【问题描述】:

我在试图弄清楚如何使这个脚本工作时遇到问题。我需要从 C:\Users 文件夹中获取用户列表(以某种方式存储在 powershell 中或保存到文本文件中),然后运行脚本删除每个用户文件夹中的某些缓存数据。因为我是根据从 AD 中提取的列表(到另一个 .txt 文件)运行它,所以我无法理解如何根据 foreach、foreach 概念运行它,其中一个脚本中有两个 foreach 语句。


$Computers = Get-Content "C:\Temp\Cache Cleanup Project\June 10 Lists\ComputerUp.txt" | foreach ($Computer in $Computers) {
dir \\$Computer\C$\Users | select Name | Out-File "C:\temp cache cleanup project\Computer Users\$Computer.txt"

我觉得我在上面的脚本中遗漏了一些东西。我需要的是一个充满 .txt 文件的文件夹,其中包含 ComputerUp.txt 文件中每台计算机名称的名称。在每个文件中都有该特定机器的用户列表。我的其他脚本将需要引用这些文件中的每一个,以便通过并清除缓存的文件。

我希望这是有道理的。我必须清理近 700 台机器上的缓存,并且必须清理每个用户配置文件,这是我能弄清楚如何做到这一点的最佳方法。如果有人有更好的建议,我会全力以赴。

【问题讨论】:

  • 关于 foreach statementForEach-Object cmdlet 之间的混淆(有点令人困惑,后者有一个 别名 也叫foreach:除了圣地亚哥的回答,见this answer
  • 我的错,@SantiagoSquarzon,我不小心粘贴了两次相同的链接:这是 Dave Wyatt 文章的存档副本,通过 Wayback Machine:web.archive.org/web/20200923025608/https://powershell.org/2013/…
  • 我的荣幸,@SantiagoSquarzon;重新枚举基准(foreach 语句与.ForEach() 方法与ForEach-Object cmdlet):我刚刚修改了this answer 中的基准,很惊讶地看到@ 987654332@ 方法比foreach 语句;如果你愿意,我很想知道你是否得到类似的结果。
  • @mklement0 对该帖子的出色回答!我喜欢性能测试,我已经对 PS 中不同循环的优缺点有所了解,这可能是我通常倾向于在我的答案中使用经典方法的原因。 Dave 的那篇文章从我读到它的那一刻起就一直是我的经验法则,而且它也很棒,因为他谈到了 PowerShell filter,这是很少人谈论的。
  • 谢谢,@SantiagoSquarzon;有趣的是,管道中的函数比.ForEach() 执行得更好。请注意,filter 只是函数(语法糖)的简化形式,具有以下等价性:filter foo { $_ }function foo { process { $_ } } 相同

标签: powershell


【解决方案1】:

我需要的是一个充满 .txt 文件的文件夹,其中包含 ComputerUp.txt 文件中每台计算机的名称

为此使用文件系统是不必要的 - 您可以将此信息存储在内存中的变量中:

# Read the list of computers from disk
$Computers = Get-Content .\path\to\ComputerUp.txt

# Create a dictionary to hold ComputerName->ListOfUsers data
$UsersPerComputer = [ordered]@{}

foreach($computer in $Computers){
  # enumerate the remote folder names
  $listOfNames = Get-ChildItem \\$Computer\C$\Users |Select-Object -ExpandProperty Name

  # assign the list to the dictionary, use the computer name as the key
  $UsersPerComputer[$computer] = $listOfNames
}

现在您可以按名称检索单台计算机的列表:

$targetMachine = 'Computer123'

$UsersPerComputer[$targetMachine] # this will resolve to the list of user folder names we got from Computer123

【讨论】:

    【解决方案2】:

    您似乎将foreachForeEach-Object 混淆了。

    • 使用foreach,您的脚本将如下所示:
    $Computers = Get-Content "C:\Temp\Cache Cleanup Project\June 10 Lists\ComputerUp.txt"
    
    foreach ($Computer in $Computers)
    {
        (Get-ChildItem "\\$Computer\C$\Users").Name |
        Out-File "C:\temp cache cleanup project\Computer Users\$Computer.txt"
    }
    
    • ForEach-Object 看起来像这样:
    Get-Content "C:\Temp\Cache Cleanup Project\June 10 Lists\ComputerUp.txt" | ForEach-Object {
        (Get-ChildItem "\\$_\C$\Users").Name |
        Out-File "C:\temp cache cleanup project\Computer Users\$_.txt"
    } 
    

    顺便说一句,这样做应该可以更快地完成工作:

    $Computers = Get-Content "C:\Temp\Cache Cleanup Project\June 10 Lists\ComputerUp.txt"
    
    $result = Invoke-Command -ComputerName $Computers -ScriptBlock {
        Get-ChildItem C:\Users
    }
    
    $result | Group-Object PSComputerName | ForEach-Object {
        $_.Group.Name | Out-File "C:\temp cache cleanup project\Computer Users\$($_.Name).txt"
    }
    

    【讨论】:

    • 这是我最终的结果:$Computers = Get-Content "C:\Temp\Cache Cleanup Project\ComputerUp.txt" $result = Invoke-Command -ComputerName $Computers -ScriptBlock { Get-ChildItem C:\Users } $result | Group-Object PSComputerName | ForEach-Object { $_.Group.Name | Out-File "C:\temp\cache cleanup project\Computer Users\$($_.Name).txt" } Invoke-Command:无法验证参数“ComputerName”上的参数。参数为 null 或空。提供一个不为 null 或空的参数,然后重试该命令。
    • @MjrPayne 检查您的输入文件中是否没有空/空格或空行。
    • 已检查并且不应该存在空格。将 Get-ChildItem 路径更改为“\\$Computers\c$\users”,但仍然出现相同的错误。
    • 我确实检查了“foreach”选项的结果文件夹,它确实产生了结果。但是,它所做的只是将计算机名称列为 .txt 文件名,而文件中没有任何内容。运行时确实会产生错误,“Get-ChildItem:找不到路径'\\\C$\Users',因为它不存在”不知道为什么会这样。由于空间限制,我将在另一条评论中发布脚本。
    • $Computers = Get-Content "C:\Temp\CacheCleanUp\ComputerUp.txt" foreach ($Computer in $Computers) { (Get-ChildItem "\\$Computer\C$\Users").Name | Out-File "C:\Temp\CacheCleanUp\Computer Users\$Computer.txt" }
    猜你喜欢
    • 2021-09-20
    • 1970-01-01
    • 1970-01-01
    • 2010-10-25
    • 2019-12-16
    • 1970-01-01
    • 1970-01-01
    • 2017-08-04
    • 2020-09-08
    相关资源
    最近更新 更多