从多个 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
}
}
您对 Path
和 Description
属性使用 $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
目标:获取包含以下信息的 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
}
}
您对 Path
和 Description
属性使用 $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