1
votes

Windows makes it difficult to create a network share with anonymous access (in other words, users who the share-hosting machine does not know about can access). The net share ShareName=C:\DesiredShareSource /GRANT:EVERYONE,FULL gives access to Everyone, but that does not include anonymous access (e.g. non-domain joined users, WITHOUT prompting credentials).

I know there's a way to do this from a GUI (https://serverfault.com/questions/272409/setting-up-an-anonymous-windows-server-2008-network-share), but is there a way changing security policies and creating anonymous network shares can be done strictly from PowerShell?

EDIT

This is what happens when I run the WMI script posted by Ansgar Wiechers. I get an exception but the share mounts successfully: share mounting with exception However, when I try and connect to the share from another box on the same network, I am still prompted for a username and password, as seen below:

still requiring username and password

Again, I want anonymous access (no username and password) to be set up all from command line.

Here is the exact code I am using in testingAnonShare.ps1, on a Win7 system:

$path        = 'C:\Users\<REDACTED>\Desktop\Attempt'
$name        = 'testinganon'
$description = 'share description'

function Get-Trustee($sid) {
  $trustee = ([wmiclass]'Win32_Trustee').CreateInstance()
  $trustee.SID = ([wmi]"Win32_SID.SID='$sid'").BinaryRepresentation
  return $trustee
}

function New-FullAce($sid) {
  $ace = ([wmiclass]'Win32_ACE').CreateInstance()
  $ace.AccessMask = 2032127  # full control
  $ace.AceFlags   = 3        # container inherit + object inherit
  $ace.AceType    = 0        # access allowed
  $ace.Trustee    = Get-Trustee $sid
  return $ace
}

$sd = ([wmiclass]'Win32_SecurityDescriptor').CreateInstance()
$sd.ControlFlags = 4
$sd.DACL         = (New-FullAce 'S-1-1-0'),
                   (New-FullAce 'S-1-5-7')

$wmi = Get-WmiObject Win32_Share -List
$wmi.Create($path, $name, 0, $null, $description, '', $sd) | Out-Null
2
net.exe SHARE ShareName=C:\DesiredShareSource /GRANT:"ANONYMOUS LOGON",FULL but in place "ANONYMOUS LOGON" must be localized string - it will be used in LookupAccountName function. however if you grant only ANONYMOUS LOGON" - usual users will no permissions here, so need add everyone too - /GRANT:Everyone,FULLRbMm
I still am prompted to enter a password when I do net SHARE ShareName=C:\DesiredShareSource /GRANT:"ANONYMOUS LOGON",FULL. Also, it requires me to put a ` before the commas in both GRANT statements. Is there any reason I am still prompted to enter credentials when I access the shares from other boxes?AlwaysQuestioning
@RbMm that's how I started here. I want to do this all from PowerShell.AlwaysQuestioning

2 Answers

3
votes

All examples create a share called test mapped to a path D:\test, granting full access to Anonymous and Everyone.

Windows Server 2012 R2 and newer

To create a share with everyone having Full access this is the command

New-SmbShare -Name 'test' -path 'D:\test' -FullAccess 'ANONYMOUS LOGON','Everyone'

To update an existing share to have the same permission is a little more complicated. First, assume the share name is test. Here is the code to change it to the same permissions as above.

Get-SmbShare -Name test | 
    Set-SmbShare -SecurityDescriptor 'O:BAG:DUD:(A;;FA;;;AN)(A;;FA;;;WD)'

To get the SecurityDescriptor string, create a share test like you want it and run the following command.

(get-smbshare -Name Test).SecurityDescriptor

Backward compatible (NET SHARE)

This can also be done with net share

net share test=D:\test /GRANT:"ANONYMOUS LOGON,FULL" /GRANT:"Everyone,FULL"
2
votes

In addition to New-SmbShare (Windows Server 2012 or newer) and net share you can also use WMI for creating network shares.

$path        = 'C:\DesiredShareSource'
$name        = 'sharename'
$description = 'share description'

function Get-Trustee($sid) {
  $trustee = ([wmiclass]'Win32_Trustee').CreateInstance()
  $trustee.SID = ([wmi]"Win32_SID.SID='$sid'").BinaryRepresentation
  return $trustee
}

function New-FullAce($sid) {
  $ace = ([wmiclass]'Win32_ACE').CreateInstance()
  $ace.AccessMask = 2032127  # full control
  $ace.AceFlags   = 3        # container inherit + object inherit
  $ace.AceType    = 0        # access allowed
  $ace.Trustee    = Get-Trustee $sid
  return $ace
}

$sd = ([wmiclass]'Win32_SecurityDescriptor').CreateInstance()
$sd.ControlFlags = 4
$sd.DACL += (New-FullAce 'S-1-1-0').PSObject.BaseObject
$sd.DACL += (New-FullAce 'S-1-5-7').PSObject.BaseObject

$wmi = Get-WmiObject Win32_Share -List
$wmi.Create($path, $name, 0, $null, $description, '', $sd) | Out-Null

S-1-1-0 and S-1-5-7 are the well-known SIDs of the Everyone and Anonymous groups respectively.

Appending each ACE separately to the DACL property is required to make the code work with PowerShell v2. In more recent version you can assign the ACEs as an array, and you also don't need to unwrap the base object:

$sd.DACL = (New-FullAce 'S-1-1-0'), (New-FullAce 'S-1-5-7')

To actually enable anonymous access to shares you also need to make three changes to the local security policy (source):

  1. Start secpol.msc.
  2. Navigate to Security Settings → Local Policies → Security Options.
  3. Change the following settings:
    • Accounts: Guest account statusEnabled
    • Network access: Let Everyone permissions apply to anonymous usersEnabled
    • Network access: Shares that can be accessed anonymouslysharename

Note that I did not have to change the setting Network access: Restrict anonymous access to Named Pipes and Shares to enable anonymous access from Windows 7 to an anonymous share on Server 2012 R2, but I did have to add NTFS permissions for the Everyone group.

$acl = Get-Acl -Path 'C:\DesiredShareSource'
$ace = New-Object Security.AccessControl.FileSystemAccessRule(
  'Everyone', 'ReadAndExecute', 'ContainerInherit, ObjectInherit', 'None', 'Allow'
)
$acl.AddAccessRule($ace)
Get-Acl -Path 'C:\DesiredShareSource' -AclObject $acl

I'm not aware of a way to make the policy changes with a script. You may be able to cook up something by wrapping secedit in PowerShell, but whenever I had to deal with secedit it turned out to be … bothersome, so I wouldn't recommend it. In a domain environment you can deploy local security policy settings via group policies, though.