我正在尝试为我的所有 windows 服务器列出所有已登录用户的列表

I am trying to make a list of all the logged in users for all of my windows servers

我正在尝试使用 powershell 获取服务器名称列表并列出 c:\users 中的所有文件夹。

我想最终将它写入一个文件,但现在我只是想将它们列出到控制台。

$m = import-csv -Path .\serverlist.csv
    
$m | Foreach-Object { 
    $flist = Invoke-Command -Computername $_ -ScriptBlock {
        Get-Childitem -Path C:\users -Directory 
    } 
    write-host $flist
}

当我尝试 运行 脚本时,我得到

Invoke-Command : One or more computer names are not valid. If you are trying to pass a URI, use the -ConnectionUri parameter, 
or pass URI objects instead of strings.
At C:\Users\omurac\Desktop\scripts\TestSnip\ImportorEachObject.ps1:4 char:32
+ ...  { $flist = Invoke-Command -Computername $_ -ScriptBlock {Get-Childit ...
+                 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    + CategoryInfo          : InvalidArgument: (System.String[]:String[]) [Invoke-Command], ArgumentException
    + FullyQualifiedErrorId : PSSessionInvalidComputerName,Microsoft.PowerShell.Commands.InvokeCommandCommand

如果我从 $m 变量写入主机,它会显示以下列表:

Name= server1
name=server2
nAME= SERVER3

等等...

有没有办法确保它将 csv 中的项目作为字符串传递?

感谢您的帮助。

比起 full-text 解释,我发现 re-code 更容易加上一些评论以获得更好的示例:

# Import CSV. Consider if it has headers or not, you can use parameters to play with them. Lets imagine CSV is something like this:
# ServerName
# localhost
# localhost
# localhost

$servers = Import-Csv -Path .\serverlist.csv

# this goes thru each server read from the CSV. By default, first row is treated as header.
foreach ($line in $servers)
{ 
    # When calling the computername, you refer the line, and to the particular column name. here we assume it is called "ServerName"
    $result = Invoke-Command -Computername $line.ServerName -ScriptBlock {
        Get-Childitem -Path C:\Users -Directory 
    } 
    # You used a write-host, what is intended for a string output.
    # As you used a Get-ChildItem, you will get an array of values. Easy & Nice way to display it is using a Format-Table output
    $result | Format-Table -AutoSize
}

谢谢。

既然你已经有了计算机列表,最好这样使用Invoke-Command

$serverlist = Import-Csv -Path .\serverlist.csv

$folderlist = Invoke-Command -ComputerName $serverlist.name -ScriptBlock {
    Get-Childitem -Path C:\users -Directory 
}

这将 运行 异步地针对每个服务器(在 windows powershell 5.1 中默认最多 32 个)而不是在 foreach 循环中一次一个。

默认返回的属性中有PSComputerName,让您知道哪些文件夹属于哪个服务器。这是上面代码返回的默认成员的完整列表。

Name               MemberType  
----               ----------  
GetType            Method      
ToString           Method      
BaseName           NoteProperty
LinkType           NoteProperty
Mode               NoteProperty
PSChildName        NoteProperty
PSComputerName     NoteProperty
PSDrive            NoteProperty
PSIsContainer      NoteProperty
PSParentPath       NoteProperty
PSPath             NoteProperty
PSProvider         NoteProperty
PSShowComputerName NoteProperty
RunspaceId         NoteProperty
Target             NoteProperty
Attributes         Property    
CreationTime       Property    
CreationTimeUtc    Property    
Exists             Property    
Extension          Property    
FullName           Property    
LastAccessTime     Property    
LastAccessTimeUtc  Property    
LastWriteTime      Property    
LastWriteTimeUtc   Property    
Name               Property    
Parent             Property    
Root               Property   

收集完$folderlist中的信息后,您可以查看、导出等

我想指出的另一件事out/recommend是变量的命名。很容易忽略单数变量和复数变量,我们总是看到它是一个看起来像这样的循环

foreach($username in $usernames){do something on $usernames}

反之亦然,所以通常的做法是像我的示例一样将它们命名为描述性的。 $serverlist$folderlist 可以轻松查看其中的内容。