McKenning
McKenning

Reputation: 641

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

GOAL: Obtain a CSV file with the following information:

for all non-admin (type 0) SMB shares on all servers from a list (txt file).

INITIAL CODE:

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

CODE OUTPUT:

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

PROBLEM:

While the code provides output for each server, it seems to not include all shares from the servers. Furthermore, the Path and Description fields are not populated with good information.

ADDITIONAL INFO:

The code:

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

Produces good information as below:

Name           Path                                Description
----           ----                                -----------
print$         C:\WINDOWS\system32\spool\drivers   Printer Drivers
Share          D:\Share
SHARE2         D:\SHARE2
Software       C:\Software                         The Software

Upvotes: 0

Views: 3212

Answers (1)

Ansgar Wiechers
Ansgar Wiechers

Reputation: 200293

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

You're using $shares instead of $_ for the Path and Description properties, so each of these properties is assigned a list of the values of the respective property of each element of the $shares collection.

Also, why are you building custom objects in the first place when you just need to filter the WMI query results? The computer name can be obtained from the __SERVER (or PSMachineName) property. Plus, type 0 means a shared disk drive, not an administrative share. You need to filter the latter by other criteria (usually description and/or share name).

$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

Upvotes: 1

Related Questions