28

I am trying to get a list of folders that are shared on a file share. At the moment I have two test folders:

\\MYPC\Test1

\\MYPC\Test2

This is the code I have at the moment:

$FileServer = Read-Host "Enter file server to search"
$FolderList = Get-ChildItem -Path $FileServer

Write-Host $FolderList

But this comes up with "cannot find the path". I can see examples of how to do this for \\Server\Share as the directory, but is it possible to just search the \\Server?

11 Answers 11

31

Try this:

get-WmiObject -class Win32_Share -computer dc1.krypted.com

Ref: List Shares in Windows w/ PowerShell

3
  • 7
    This would require WMI rights on the destination machine, which isn't a particularly portable solution. Jun 17, 2014 at 2:52
  • 6
    plus, it would require RPC communications, which are likely to be firewalled in many configurations even where generic SMB is permitted. Admittedly, net view would not return hidden shares. Jun 17, 2014 at 9:10
  • Does it use the SMB protocol to retrieve the list? Or does it use the "Powershell" protocol to list the share? Oct 11, 2021 at 7:22
22

Powershell is not able too use SMB protocol in order to list the shares on a remote computer. There's only one way of enumerating shares remotely from the command line that I know of, and thats with net view:

C:\Users\mark.henderson>net view \\enetsqnap01
Shared resources at \\enetsqnap01



Share name             Type  Used as  Comment

-------------------------------------------------------------------------------
Backups                Disk
CallRecordings         Disk
Download               Disk           System default share
home                   Disk           Home
homes                  Disk           System default share
Installs               Disk
Justin                 Disk           Copy of files from Justin laptop
michael                Disk
Multimedia             Disk           System default share
Network Recycle Bin 1  Disk           [RAID5 Disk Volume: Drive 1 2 3 4]
Public                 Disk           System default share
Qsync                  Disk           Qsync
Recordings             Disk           System default share
Sales                  Disk           Sales Documents
SalesMechanix          Disk
Server2012             Disk           Windows Server 2012 Install Media
Usb                    Disk           System default share
VMWareTemplates        Disk
Web                    Disk           System default share
The command completed successfully.

This is not particularly parsable on its own, but, you can throw it into an array to process the data line by line:

$sharedFolders = (NET.EXE VIEW \\enetsqnap01) 

You now have an array, and starting at $sharedFolders[7] you have your shares. You could then split on something like a double space - unlikely to appear in a share name itself, and should work unless your share name is very long, only leaving a single space between the share name and the type field:

$sharedFolders[7].split('  ')[0]
Backups

You could process these by using a ForEach and some conditional logic. It wouldn't be perfect, but it should work for most use cases.

For brevity, to just output the filenames to the console:

(net view \\enetsqnap01) | % { if($_.IndexOf(' Disk ') -gt 0){ $_.Split('  ')[0] } }
3
  • FYI: I added a helper function to wrap up the call and break down the text output in a semi-intelligent way... hopefully it makes sense / helps some people out there.
    – JohnLBevan
    May 20, 2016 at 14:46
  • 1
    @JohnLBevan I don't see it here. Maybe the edit got rejected? If you submit it again I'll see if I can review it in time before someone else gets to it. May 20, 2016 at 21:10
  • Thanks @Mark Henderson. From the review notes (superuser.com/review/suggested-edits/535793) it seems people would prefer me to post my code in a separate answer, so I've posted here: superuser.com/a/1079174/156700 . Hope this is useful to others. Thanks again for your solution.
    – JohnLBevan
    May 20, 2016 at 22:22
17

If you want to find the shares of the local machine you can just do Get-SmbShare:

> Get-SmbShare

Name                          ScopeName                     Path                          Description
----                          ---------                     ----                          -----------
ADMIN$                        *                             C:\WINDOWS                    Remote Admin
C$                            *                             C:\                           Default share
2
  • Does Get-SmbShare command enables to list shares on a remote computer? Oct 11, 2021 at 7:37
  • @MUYBelgium No, it only retrieves the share information for the local computer. You could use PowerShell's Invoke-Command to run it on a remote computer though.
    – JamieSee
    Dec 14, 2021 at 4:19
4

Expanding on Mark Henderson's answer:

$Servers = ( Get-ADComputer -Filter { DNSHostName -Like '*' }  | Select -Expand Name )
foreach ($Server in $Servers)
{
    (net view $Server) | % { if($_.IndexOf(' Disk ') -gt 0){ $_.Split('      ')[0] } } | out-file C:\file_shares\$Server.txt
}
1
  • 3
    Can you explain what your expansions do?
    – bertieb
    Sep 15, 2015 at 8:01
3

Thanks to Mark Henderson for his solution. I've added a wrapper function to help make this function call more PowerShell friendly. I've used a different approach to breaking up the data (more complex, not better); that can easily be switched around based on preference.

clear-host
function Get-SharedFolder {
    [CmdletBinding()]
    param(
        [Parameter(Mandatory = $true, ValueFromPipeline = $true)]
        [string]$ComputerName 
        ,
        [Parameter(Mandatory = $false)]
        [switch]$GetItem
        ,
        [Parameter(Mandatory = $false)]
        [string[]]$ColumnHeadings = @('Share name','Type','Used as','Comment')  #I suspect these differ depending on OS language?  Therefore made customisable
        ,
        [Parameter(Mandatory = $false)]
        [string]$ShareName = 'Share name' #tell us which of the properties relates to the share name
        #,
        #[Parameter(Mandatory = $false)]
        #[string[]]$Types = @('Disk') # again, likely differs with language.  Also there may be other types to include?
    )
    begin {
        [psobject[]]$Splitter = $ColumnHeadings | %{
            $ColumnHeading = $_
            $obj = new-object -TypeName PSObject -Property @{
                Name = $ColumnHeading
                StartIndex = 0
                Length = 0
            }
            $obj | Add-Member -Name Initialise -MemberType ScriptMethod {
                param([string]$header)
                process {
                    $_.StartIndex = $header.indexOf($_.Name)
                    $_.Length = ($header -replace ".*($($_.Name)\s*).*",'$1').Length
                }
            }
            $obj | Add-Member -Name GetValue -MemberType ScriptMethod {
                param([string]$line)
                process {
                    $line -replace ".{$($_.StartIndex)}(.{$($_.Length)}).*",'$1'
                }
            }
            $obj | Add-Member -Name Process -MemberType ScriptMethod {
                param([psobject]$obj,[string]$line)
                process {
                    $obj | Add-Member -Name $_.Name -MemberType NoteProperty -Value ($_.GetValue($line))
                }
            }
            $obj
        }
    }
    process {
        [string[]]$output = (NET.EXE VIEW $ComputerName)
        [string]$headers = $output[4] #find the data's heading row
        $output = $output[7..($output.Length-3)] #keep only the data rows
        $Splitter | %{$_.Initialise($headers)}
        foreach($line in $output) { 
            [psobject]$result = new-object -TypeName PSObject -Property @{ComputerName=$ComputerName;}
            $Splitter | %{$_.Process($result,$line)}
            $result | Add-Member '_ShareNameColumnName' -MemberType NoteProperty -Value $ShareName
            $result | Add-Member 'Path' -MemberType ScriptProperty -Value {("\\{0}\{1}" -f $this.ComputerName,$this."$($this._ShareNameColumnName)")}
            $result | Add-Member 'Item' -MemberType ScriptProperty -Value {Get-Item ($this.Path)}
            $result | Add-Member -MemberType MemberSet -Name PSStandardMembers -Value ([System.Management.Automation.PSMemberInfo[]]@(New-Object System.Management.Automation.PSPropertySet(‘DefaultDisplayPropertySet’,[string[]](@('ComputerName','Path') + $ColumnHeadings))))
            $result
        }
    }
}

[string[]]$myServers = 'myServer1','myServer2' #amend this line to get the servers you're interested in
[psobject[]]$shares = $myServers | Get-SharedFolder
write-host 'List of Shares' -ForegroundColor Cyan
$shares  | ft -AutoSize
write-host 'Shares as Get-Item output' -ForegroundColor Cyan
$shares  | select -expand Item
1

On Windows 8 or higher and Windows Server 2012 or higher, you can use Get-SmbShare from the SmbShare module.

1
  • Does Get-SmbShare command enables to list shares on a remote computer? Oct 11, 2021 at 7:38
0

Windows Resource Kit tool: rmtshare.

Either run under id with administrator permissions on the remote server or make an ipc$ connection to remote server.

rmtshare \\servername
1
  • Can you expand your answer a bit more to include the steps needed to solve the problem?
    – Cfinley
    Apr 10, 2015 at 17:59
0

Here's a PowerShell one liner that uses net view to enumerate all remote shares a user can see - doesn't mean they have access.

net view | Where {$_ -like "\\*"} | %{$comp = $_.Split(" ")[0]; net view $comp | Where {$_ -like "*Disk*"} | %{$share = $_.Split(" ")[0]; $fullpath = Join-Path $comp $share; $fullpath}}

If you want to see if they have (at least) read access, you can run:

Net view | Where {$_ -like "\\*"} | %{$comp = $_.Split(" ")[0]; net view $comp | Where {$_ -like "*Disk*"} | %{$share = $_.Split(" ")[0]; $fullpath = Join-Path $comp $share; [PSCustomObject]@{Path=$fullpath;HasAccess=$(Test-Path $fullpath -ErrorAction SilentlyContinue)}}}

If you need the output saved you can always pipe it to Export-CSV by throwing the following on after the last bracket:

| Export-CSV "\\path\to\file.csv" -NoTypeInformation

The whole thing is not perfect when net view throws an error but I wrote it based on the comments here and it works pretty well and is helpful for what I need so I thought I'd share. :)

0

Not a real answer.

Just some tidbits. And several things that did NOT work.

Did not work: get-WmiObject

PS C:\> get-WmiObject -class Win32_Share -computer myserver.example.com

Did not work: get-fileshare

https://docs.microsoft.com/en-us/powershell/module/storage/get-fileshare

Did not work: get-smbshare

https://docs.microsoft.com/en-us/powershell/module/smbshare/get-smbshare

Worked: Cygwin/Mobaxterm

Moba (https://mobaxterm.mobatek.net/) will access file shares just fine.

"list all available shares for that server" mode Both these forms work:

$ ls //myserver.example.com/
a b c

$ ls '\\myserver.example.com\'
a b c

"list the contents of a SPECIFIC share on that server" mode Both these forms work:

$ ls //myserver.example.com/a
foo bar baz

$ ls '\\myserver.example.com\a'
foo bar baz

Advantages: Moba does NOT differentiate between the "list all available shares for that server" mode and the "list the contents of a SPECIFIC share on that server" mode. -- Which seems to be major obstacle in PowerShell.

Drawbacks:

  • Extra install
  • Not PowerShell. Purely text. Not an objectlike .NET/Windows way of doing this at all.

Worked: net view

Advantages:

  • preinstalled on Windows

Drawbacks: Not PowerShell. Purely text. Not an objectlike .NET/Windows way of doing this at all.

1
  • I tried stupids answers hereover and know why they do not do the job. May be you should say why thinks does not work. Oct 11, 2021 at 7:42
0

I keep hearing "No you can't get a list of shared folders from a server using get-WmiObject. Yet for me, I have been successful in using get-WmiObject to collect a list of all shared folders off my servers from my workstation using the instructions above (see image attached). If I export to a csv, I get a whole lot of other information beside just the names and where the shares live.

shared folders

1
  • 1
    Your answer could be improved with additional supporting information. Please edit to add further details, such as citations or documentation, so that others can confirm that your answer is correct. You can find more information on how to write good answers in the help center.
    – Community Bot
    Feb 15, 2022 at 21:26
0

I use the following based on Dingo's answer.

Create a file called get_shares.ps1 with this content:

#$Servers = ( Get-ADComputer -Filter { DNSHostName -Like '*' }  | Select -Expand Name )
$Servers = @('server-01', 'server-02')
foreach ($Server in $Servers)
{
    (net view $Server /all) | %{
        if($_.IndexOf(' Disk ') -gt 0)
        {
            $shareName = $_.Split('      ')[0]
            Write-Host "\\$Server\$shareName"
        }
    }
}

Then run it using:

powershell -executionpolicy bypass ./get_shares.ps1

It produces output such as:

\\server-01\data
\\server-01\some_hidden_share$
\\server-02\c$
\\server-02\logs

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .