从多个 Windows 服务器获取非管理文件共享列表

Obtain a list of non-admin file shares from multiple Windows servers

目标:获取包含以下信息的 CSV 文件:

对于列表(txt 文件)中所有服务器上的所有非管理员(类型 0)SMB 共享。

初始代码:

param (
    [Parameter(Mandatory=$true,Position=0)]
    [ValidateNotNullOrEmpty()]
    [String]
    $path
)

$computers = Get-Content $path
$shareInfo = @()

ForEach ($computer in $computers) {
    $shares = gwmi -Computer $computer -Class Win32_Share -filter "Type = 0" | Select Name,Path,Description

    $shares | % {
        $ShareName = $_.Name
        $Props = [ordered]@{
            Computer = $computer
            ShareName = $_.Name
            Path = $shares.Path
            Description = $shares.Description
        }
    }

    $ShareInfo += New-Object -TypeName PSObject -Property $Props
}

$shareInfo | Export-CSV -Path .\shares.csv -NoType

代码输出:

"Computer","ShareName","Path","Description"
"SERVER1","SHARE1","System.Object[]","System.Object[]"
"SERVER2","SHARE12","System.Object[]","System.Object[]"
"SERVER3","SHARE3","System.Object[]","System.Object[]"

问题:

虽然代码为每台服务器提供输出,但它似乎不包括来自服务器的所有共享。此外,路径和描述字段未填充有用信息。

附加信息:

代码:

$shares = gwmi -Computer $computer -Class Win32_Share -filter "Type = 0" | Select Name,Path,Description

产生如下良好信息:

Name           Path                                Description
----           ----                                -----------
print$         C:\WINDOWS\system32\spool\drivers   Printer Drivers
Share          D:\Share
SHARE2         D:\SHARE2
Software       C:\Software                         The Software
$shares | % {
    $ShareName = $_.Name
    $Props = [ordered]@{
        Computer = $computer
        ShareName = $_.Name
        Path = $shares.Path
        Description = $shares.Description
    }
}

您对 PathDescription 属性使用 $shares 而不是 $_,因此为这些属性中的每一个分配了一个值列表$shares 集合的每个元素各自的 属性。

另外,当您只需要过滤 WMI 查询结果时,为什么要首先构建自定义对象?计算机名称可以从__SERVER(或PSMachineName)属性中获取。另外,类型 0 表示共享磁盘驱动器,而不是管理共享。您需要通过其他条件(通常是描述 and/or 共享名称)过滤后者。

$filter = "Type = 0 And Description != 'Default Share' And " +
          "Name != 'ADMIN$' And Name != 'IPC$'"

$computers |
  ForEach-Object { Get-WmiObject -Computer $_ -Class Win32_Share -Filter $filter } |
  Select-Object @{n='Computer';e={$_.__SERVER}}, Name, Path, Description |
  Export-Csv -Path .\shares.csv -NoType