Powershell – WMI: Working with Shares – Part 1: Creating a Share with Custom Permissions

Download Script:

Download “NewShareWithPermissions-0.0.1.zip” newsharewithpermissions-001.zip – Downloaded 1905 times – 2 KB

Intro:

Last week, i was teaching a Powershell course (MOC6434), when a student asked me, how to create a share with custom permissions via WMI.

I tried to find an answer for him, but could not really find any examples, cmdlets or functions for it.

I found some examples and help in vbscript, so i decided to make some powershell functions of my own.

I Created these functions that uses the Win32_Share class of WMI. They support remote creation and multiple permissions.

New-Share is for creating a share.

New-ACE is for creating one or more ACEs for use with New-Share

New-SecurityDescriptor is used by New-Share to combine the ACE’s into a SecurityDescriptor for the WMI Method.

Functions:

New-Share

SYNOPSIS
Creates a new Share on local or remote PC. Support for Custom Permissions

SYNTAX
New-Share [-FolderPath] <string> [-ShareName] <string> [-ACEs <Win32_ACE Object>] [-Description <string>] [-Computer] <string>

DETAILED DESCRIPTION
Create new share, either on local or remote PC.

Shares can be created without the use of –ACEs parameter, this will create a share with standard permissions. If the ACEs parameter if used, custom permissions can be added.

PARAMETERS

FolderPath <string>
Specifies the local path for folder that is to be shared.

Required? true
Position? 1
Default value
Accept pipeline input? false
Accept wildcard characters? false

ShareName <string>
Specifies the name of the share.

Please notice that duplicate share names are not supported in windows.

Required? true
Position? 2
Default value
Accept pipeline input? false
Accept wildcard characters? false

ACEs <(Array of) Win32_ACE Objects>
Specifies the custom permissions.
Create the Win32_ACE object by using New-ACE function.
This parameter either support a single object or an array of objects

Required? false
Position? 3
Default value
Accept pipeline input? false
Accept wildcard characters? false

Description <string>
Description for the share

Required? false
Position? 4
Default value
Accept pipeline input? false
Accept wildcard characters? false

Computer <string>
Specify computername for the target computer

Required? false
Position? 4
Default value . (localhost)
Accept pipeline input? false
Accept wildcard characters? false

INPUT TYPE
No Pipe input in version 0.0.1

RETURN TYPE
System.Object
Properties: ReturnCode, Message

————————– EXAMPLE 1 ————————–

$ACE = New-ACE -Name “Domain Users” -Domain “CORETECH” -Permission “Read” -Group
New-Share -FolderPath “C:\Temp” -ShareName “Temp4”  -ACEs $ACE
–Description "Test Description" -Computer "localhost"

This examples creates one Win32_ACE object that specifies "CORETECH\Domain Users", to have read permission and use it to share C:\Temp on the local machine.

-------------------------- EXAMPLE 2 --------------------------

$ACE = New-ACE -Name "Domain Users" -Domain "CORETECH" -Permission "Read" -Group
$ACE2 = New-ACE -Name "CCO" -Domain "CORETECH" -Permission "Full"
New-Share -FolderPath "C:\Temp" -ShareName "Temp4"  -ACEs $ACE,$ACE2

-Description “Test Description” -Computer “localhost”

This examples create both a users ACE and a group ACE, and send them both with the New-Share function

————————– EXAMPLE 3 ————————–

New-Share “C:\Temp” “Temp4”

This is the shortest way to run the function. Using default permissions (which is decided from whom, who run the function). and using position parameters, ignoring all optional parameters

New-ACE

SYNOPSIS
Creates a Win32_ACE object contains permissions for use with New-share (or another function that need Win32_ACE objects)

SYNTAX
New-ACE [-Name] <string> [-Domain] <string> [-Permission] <string> [-Computer <string>] [-Group]

NOTICE

Due to the limitations of the WMI_Account class, it is only possible to get local accounts when connecting to WMI via a remote machine (as far as i know, please contact me if you have input).

This means that usually you should not use the –ComputerName paramter, only use it if you are connecting to a workgroup computer, and using local user/groups for the permissions

PARAMETERS

Name <string>
Specifies the name of the user or group.

Required? true
Position? 1
Default value
Accept pipeline input? false
Accept wildcard characters? false

Domain <string>
Specifies the domain for the user or group.

Required? true
Position? 2
Default value
Accept pipeline input? false
Accept wildcard characters? false

Permission <string>
Specifies the permission granted for the user/group.

Possible values are “Read”, “Change”, “Full”

Required? true
Position? 3
Default value
Accept pipeline input? false
Accept wildcard characters? false

Computername <string>
Specify computername for the target computer to get the user info from.
NB! Please read the Notice above this.

Required? false
Position? 4
Default value . (localhost)
Accept pipeline input? false
Accept wildcard characters? false

Group <switch>
This is a switch parameter, add it if you are creating an ACE for a group instead of a user.

Required? false
Position? 5
Default value
Accept pipeline input? false
Accept wildcard characters? false

INPUT TYPE
No Pipe input in version 0.0.1

RETURN TYPE
Win32_ACE Object

————————– EXAMPLE 1 ————————–

New-ACE -Name “Domain Users” -Domain “CORETECH” -Permission “Read” -Group

This examples creates one Win32_ACE object that specifies “CORETECH\Domain Users”.

————————– EXAMPLE 2 ————————–

$ACE2 = New-ACE -Name “CCO” -Domain “CORETECH” -Permission “Full”

This examples creates a user ACE

New-SecurityDescriptor

SYNOPSIS
Creates a Win32_SecurityDescriptor object from on or more Win32_ACEs, for use by New-Share.

SYNTAX
New-SecurityDescriptor [-ACEs] <[array of] Win32_ACE Object(s)> [-ComputerName <string>]

NOTICE

Due to the limitations of the WMI_Account class, it is only possible to get local accounts when connecting to WMI via a remote machine (as far as i know, please contact me if you have input).

This means that usually you should not use the –ComputerName paramter, only use it if you are connecting to a workgroup computer, and using local user/groups for the permissions

PARAMETERS

ACEs <[Array of] Win32_ACE object(s)>
Specifies one or more Win32ACE object that should be added to the SecurityDescriptor

Required? true
Position? 1
Default value
Accept pipeline input? false
Accept wildcard characters? false

ComputerName <string>
Specify computername for the target computer to get the user info from.
NB! Please read the Notice above this.

Required? false
Position? 2
Default value . (localhost)
Accept pipeline input? false
Accept wildcard characters? false

INPUT TYPE
No Pipe input in version 0.0.1

RETURN TYPE
Win32_SecurityDescriptor Object

————————– EXAMPLE 1 ————————–

$ACE = New-ACE -Name “Domain Users” -Domain “CORETECH” -Permission “Read” –Group
New-SecurityDescriptor $ACE

This examples creates a Win32_SecurityDescriptor from one Win32_ACE object

————————– EXAMPLE 2 ————————–

$ACE = New-ACE -Name “Domain Users” -Domain “CORETECH” -Permission “Read” –Group
$ACE2 = New-ACE -Name “CCO” -Domain “CORETECH” -Permission “Full”
New-SecurityDescriptor $ACE,$ACE2

This examples creates a Win32_SecurityDescriptor from more than one Win32_ACE object

Source:


Last Words:

Script is version 0.0.1. Tested on Windows Vista and Windows XP local and remote, in my enviroment.

There might be a lot that i have not thought of yet, please comment this post if you have suggestions/bugs/

Next Part:

Next time i will try to look into changing existing shares, adding and remove permissions to the list.

Replacing the permissions seems easy, but editing the existing ones might be a challenge.

I will look at it as soon as i have some spare time 🙂

As usual, please contact me/us if you need any help on a custom scripting project (at standard price rate of cause).

I hope you all have a nice summer!

By | 2009-07-01T11:37:26+00:00 July 1st, 2009|Powershell, Scripting & Development|39 Comments

About the Author:

Jakob Gottlieb Svendsen

Twitter: @JakobGSvendsen

Jakob Gottlieb Svendsen is a Microsoft Cloud and Data Center Management MVP (http://mvp.microsoft.com/en-us/default.aspx), Working as Global Lead Developer, Senior Consultant and Trainer at CTGlobal, where he is one of the driving forces in keeping CTGlobal a System Center Gold Partner and member of the System Center Alliance.

Since he started at Coretech in 2007, he has focused on Scripting and Development, primarily developing tools, extensions and scripts for the System Center Suite. His main area is Automation (including OMS/Azure Automation, Service Management Automation, PowerShell and Orchestrator). Another area is Windows Azure Pack / Azure Stack, where he does implementation, development, workshops and presentations. He is a world-wide renowned voice in the Automation field.

He is passionately devoted to the community, to which he contributes by being a moderator at TechNet and sharing his knowledge at http://blog.ctglobalservices.com/jgs

  • Co-founder: PowerShell User Group Denmark
  • Speaker at MMS 2016, Minneapolis (www.mmsmoa.com)
  • SCU Europe 2014, 2015, 2016 (www.systemcenteruniverse.ch)
  • Microsoft TechEd North America 2014, Houston
  • NIC 2012,2013,2014,2015, Oslo (www.nic.com)
  • Microsoft CampusDays 2011, 2013, Copenhagen
  • Microsoft TechDays 2015, Sweden (www.techdays.se)
  • Microsoft Partner Event: New in SC2012 SP1
  • User group meetings (PSUG.DK , SCUG.DK/BE/NO, AZMUG + more)
  • Microsoft Certified Trainer.
  • Microsoft Scripting Guys Forum Moderator

Main working areas:

  • Automation (Azure Automation, SMA, SCO)
  • Windows Azure Pack / Azure Stack
  • System CenterVisual Studio Team Services / Team Foundation Server
  • Development:C#.Net, VB.NET, VBScript, PowerShell, Service Manager, OpsMgr, ConfigMgr
  • Orchestrator
  • Windows Azure Pack / Azure Stack

Training:

  • Azure Automation
  • Service Management Automation
  • System Center Orchestrator
  • PowerShell, VBScript, C#.Net, VB.Net
  • Windows Azure Pack / Azure Stack Development Workshops

39 Comments

  1. James September 21, 2009 at 23:34 - Reply

    Nice script. I had to modify it slightly for my env though.

    This line:
    $result = $Share.Create($FolderPath, $ShareName, 0, $false , $Description, $false, $SecDesc)

    Changed to this:
    $result = $Share.Create($FolderPath, $ShareName, 0, $null , $Description, $null, $SecDesc)

    The $null’s work better for the optional arguments. Especially argument 4. Maximum users. I found $false was setting it to 0. So nobody could connect to the share.

    James

  2. Jakob September 22, 2009 at 10:08 - Reply

    Great to hear that someone is using my script 😉

    and thanks alot for the bug fix! 🙂

  3. Tom September 29, 2009 at 15:28 - Reply

    Hello!

    Thanks!!! Your script rescued my goal to create a script for sharing folders remote.

    But I’ve two problems.
    – How can I change the “user limit” in the creating share from now 1 user to “maximum allowed”?
    – How can I grant access to the created share to the “Authenticated Users”?

    Maybe you have an idea….

    thanks a lot
    Tom

  4. Jonathan Warnken December 16, 2009 at 22:47 - Reply

    Nice work!!
    I added support for setting permissions for Everyone and Authenticated users. Also Updated the New-Share function to address the bug James found.

    # //************************************************************************************************************
    # // ***** Script Header *****
    # //
    # // Solution: Coretech Share Functions
    # // File: NewShareWithPermission.ps1
    # // Author: Jakob Gottlieb Svendsen, Coretech A/S. http://blog.coretech.dk
    # // Purpose:
    # // New-Share: Creates new Share on local or remote PC, with custom permissions.
    # // Required Parameters: FolderPath, ShareName
    # //
    # // New-ACE: Creates ACE Objects, for use when running New-Share.
    # // Required Parameters: Name, Domain
    # //
    # // New-SecurityDescriptor: used by New-Share to prepare the permissions.
    # // Required Parameters: ACEs
    #//
    # // Usage Examples:
    # // New-Share -FolderPath “C:Temp” -ShareName “Temp” -ACEs $ACE,$ACE2 -Description “Test Description” -Computer “localhost”
    # // Sharing of folder C:Temp, with the Name “Temp”. ACE’s (Permissions) are sent via the -ACEs parameter.
    # // Create them with New-ACE and send one or more, seperated by comma (or create and array and use that)
    # //
    # // This is the first in a couple of share-administration scripts i am planning to make and release on the blog.
    # //
    # // Please comment the blog post, if you have any suggestions, questions or feedback.
    # // Contact me if you need us to make a custom script (or cause not for free )
    # //
    # // CORETECH A/S History:
    # // 0.0.1 JGS 30/06/2009 Created initial version.
    # //
    # // Customer History:
    # // 0.0.2 – Jonathan Warnken(jon.warnken@gmail.com) 16/12/2009
    # // – Added logic to all permissions to be set using Everyone and Authenticated Users. These use well known SIDs and are easier to hard code then lookup.
    # // – Usage Examples:
    # // – (Everyone) $ACE = New-ACE -Name “Everyone” -Domain “.” -Permission “Read” -Group
    # // – (Authenticated Users) $ACE = New-ACE -Name “Authenticated Users” -Domain “NT AUTHORITY” -Permission “Read” -Group
    # // –
    # // – Updated New-Share so that -MaxUsers and -Password are optional parameters. The default values are $null.
    # // – Updated the Main Code examples to use an Array for the Access Control objects
    # //
    # // ***** End Header *****
    # //**************************************************************************************************************
    #//—————————————————————————-
    #// Procedures
    #//—————————————————————————-

    Function New-SecurityDescriptor (
    $ACEs = (throw “Missing one or more Trustees”),
    [string] $ComputerName = “.”)
    {
    #Create SeCDesc object
    $SecDesc = ([WMIClass] “\$ComputerNamerootcimv2:Win32_SecurityDescriptor”).CreateInstance()
    #Check if input is an array or not.
    if ($ACEs -is [System.Array])
    {
    #Add Each ACE from the ACE array
    foreach ($ACE in $ACEs )
    {
    $SecDesc.DACL += $ACE.psobject.baseobject
    }
    }
    else
    {
    #Add the ACE
    $SecDesc.DACL = $ACEs
    }
    #Return the security Descriptor
    return $SecDesc
    }

    Function New-ACE (
    [string] $Name = (throw “Please provide user/group name for trustee”),
    [string] $Domain = (throw “Please provide Domain name for trustee”),
    [string] $Permission = “Read”,
    [string] $ComputerName = “.”,
    [switch] $Group = $false)
    {
    #Create the Trusteee Object
    $Trustee = ([WMIClass] “\$ComputerNamerootcimv2:Win32_Trustee”).CreateInstance()
    #Check for Special cases Everyone and Authenticated Users)
    switch ($Name.ToUpper()) {
    “EVERYONE” {
    $Trustee.Domain = $Null
    $Trustee.Name = “EVERYONE”
    $Trustee.SID = @(1, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0)
    }
    “AUTHENTICATED USERS” {
    $Trustee.Domain = “NT AUTHORITY”
    $Trustee.Name = “Authenticated Users”
    $Trustee.SID = @(1, 1, 0, 0, 0, 0, 0, 5, 11, 0, 0, 0)
    }
    default {
    #Search for the user or group, depending on the -Group switch
    if (!$group)
    { $account = [WMI] “\$ComputerNamerootcimv2:Win32_Account.Name=’$Name’,Domain=’$Domain'” }
    else
    { $account = [WMI] “\$ComputerNamerootcimv2:Win32_Group.Name=’$Name’,Domain=’$Domain'” }
    #Get the SID for the found account.
    $accountSID = [WMI] “\$ComputerNamerootcimv2:Win32_SID.SID=’$($account.sid)'”
    #Setup Trusteee object
    $Trustee.Domain = $Domain
    $Trustee.Name = $Name
    $Trustee.SID = $accountSID.BinaryRepresentation
    }
    }
    #Create ACE (Access Control List) object.
    $ACE = ([WMIClass] “\$ComputerNamerootcimv2:Win32_ACE”).CreateInstance()
    #Select the AccessMask depending on the -Permission parameter
    switch ($Permission)
    {
    “Read” { $ACE.AccessMask = 1179817 }
    “Change” { $ACE.AccessMask = 1245631 }
    “Full” { $ACE.AccessMask = 2032127 }
    default { throw “$Permission is not a supported permission value. Possible values are ‘Read’,’Change’,’Full'” }
    }
    #Setup the rest of the ACE.
    $ACE.AceFlags = 3
    $ACE.AceType = 0
    $ACE.Trustee = $Trustee
    #Return the ACE
    return $ACE
    }

    Function New-Share (
    [string] $FolderPath = (throw “Please provide the share folder path (FolderPath)”),
    [string] $ShareName = (throw “Please provide the Share Name”),
    $ACEs,
    [string] $Description = “”,
    [string] $ComputerName = “.”,
    $MaxUsers = $null,
    $Password = $null)
    {
    #Start the Text for the message.
    $text = “$ShareName ($FolderPath): ”
    #Package the SecurityDescriptor via the New-SecurityDescriptor Function.
    $SecDesc = New-SecurityDescriptor $ACEs
    #Create the share via WMI, get the return code and create the return message.
    $Share = [WMICLASS] “\$ComputerNameRootCimv2:Win32_Share”
    $result = $Share.Create($FolderPath, $ShareName, 0, $MaxUsers, $Description, $Password, $SecDesc)
    switch ($result.ReturnValue)
    {
    0 {$text += “has been success fully created” }
    2 {$text += “Error 2: Access Denied” }
    8 {$text += “Error 8: Unknown Failure” }
    9 {$text += “Error 9: Invalid Name”}
    10 {$text += “Error 10: Invalid Level” }
    21 {$text += “Error 21: Invalid Parameter” }
    22 {$text += “Error 22 : Duplicate Share”}
    23 {$text += “Error 23: Redirected Path” }
    24 {$text += “Error 24: Unknown Device or Directory” }
    25 {$text += “Error 25: Net Name Not Found” }
    }
    #Create Custom return object and Add results
    $return = New-Object System.Object
    $return | Add-Member -type NoteProperty -name ReturnCode -value $result.ReturnValue
    $return | Add-Member -type NoteProperty -name Message -value $text
    #Return result object
    $return
    }

    #//—————————————————————————-
    #// Main routines
    #//—————————————————————————-

    #Create ACE’s for the securitydescriptor for the share:
    #a group ACE, containing Group info, please notice the -Group switch
    $ACE = @(New-ACE -Name “Domain Users” -Domain “CORETECH” -Permission “Read” -Group)
    $ACE += New-ACE -Name “Authenticated Users” -Domain “NT AUTHORITY” -Permission “Read” -Group
    $ACE += New-ACE -Name “everyone” -Domain “.” -Permission “Read” -Group
    #a user ACE.
    $ACE += New-ACE -Name “CCO” -Domain “CORETECH” -Permission “Full”

    #Create the share on the local machine
    $result = New-Share -FolderPath “C:Temp” -ShareName “Temp4” -ACEs $ACE -Description “Test Description” -Computer “localhost”

    #Output result message from new-share
    Write-Output $result.Message

    #Check if the share was succesfully created
    If ($result.ReturnCode -eq 0)
    {
    #Creation was succesfull, put your next code here.
    }

    #//—————————————————————————-
    #// End Script
    #//—————————————————————————-

  5. Jakob December 17, 2009 at 11:23 - Reply

    thnx alot!

    i havent had time myself to do it, its great to see other helping out!

    merry christmas to you all.

  6. Joe March 4, 2010 at 21:02 - Reply

    Thank you so much for this script. It saved me a lot of time.

  7. name required May 20, 2010 at 0:09 - Reply

    anyone copy/pasting this script be aware the content has funky single and double quotes that will need to be converted back to regular old keyboard quotes. Otherwise works g-r-e-a-t!

  8. Jakob May 20, 2010 at 9:40 - Reply

    Hello

    Yes sometimes the browsers change the chars.

    use the download link in the top of the page to download a zip file containing the script 🙂

    Best Regards
    Jakob

  9. eric June 17, 2010 at 22:52 - Reply

    Very new(1 week) to PowerShell but I got your code working in XP-Pro-32bit and I love it.

    Any chance that all will work in XP-Pro-64bit as well as Windows7?

    thank you very much…eric

  10. Jakob June 18, 2010 at 10:06 - Reply

    Hello eric!

    Nice to know it is working for you!

    I don’t see any reason it shouldnt work in Win XP PRo 64bit. but I have not tested it myself, if it does not work, please post your feedback/problems 🙂

    Best regards
    Jakob

  11. eric June 18, 2010 at 21:43 - Reply

    Jakob,
    Old version(0.0.1) works fine for me. The new version(0.0.2) fails on New-ACE.
    Can you spot what I am doing wrong or is the new version ready to download???
    Thank you-eric

    #Delete the Folder
    Remove-Item “C:PowerShellTest*” -recurse

    #Create the Folder/Directory
    New-Item “C:PowerShellTest” -type directory -force

    #Create permission to the AccessControlEntry(ACE)
    $ACE = @(New-ACE -Name “ericg” -Domain “cbo” -Permission “Read”)
    $ACE += New-ACE -Name “peggyg” -Domain “cbo” -Permission “Read”
    $ACE += New-ACE -Name “georgiab” -Domain “cbo” -Permission “Read”

    #Create the New Share
    $result = New-Share -FolderPath “C:PowerShellTest” -ShareName “PSTestShare” -ACEs $ACE -Descrition “TestDescription” -Computer “w-66898”

    Write-Output $result.Message

    if ($result.ReturnCode -eq 0)
    {
    #Creation was succesfull
    }

  12. Jakob June 21, 2010 at 10:14 - Reply

    Hello Eric

    i cannot see anything wrong in your syntax, i could be wrong tho.

    It is really hard, next to impossible to help you, when you have not included the error message you are getting.

    unfortunately there is no new version in development at the moment, i have too many other projects that need my work at the moment.

    Best regards
    Jakob

  13. Juergen August 25, 2010 at 17:50 - Reply

    Hello Jakob!

    Thanks for this great Example! I tried it but it’s not working.

    I get the following Error
    “Cannot convert value “\Serverrootcimv2:Win32_Group.Name=’Domain Users’,Domain=’dom'” to type “System.Management.ManagementObject”. Error: “Not found ” ”

    As you can see it’s in the line for getting the $account object.

    As Domain Users really exists I do not understand the error.
    maybe you can help me.

    Thanks and regards
    Juergen

  14. Juergen August 26, 2010 at 9:50 - Reply

    Hello again!

    I’ve found the solution and maybe you can explain me. The computername in function New-Ace hast to be “.” Why?

    regards

  15. Jakob August 26, 2010 at 13:03 - Reply

    Hello Juergen!

    you are correct, there is a problem there.

    i have also described it in the post

    “NOTICE

    Due to the limitations of the WMI_Account class, it is only possible to get local accounts when connecting to WMI via a remote machine (as far as i know, please contact me if you have input).”

    I don’t know why, and unfortunately i have not had time to do more powershell scripts with shares.

    Best regards
    Jakob

  16. Greg McCarty February 9, 2011 at 12:53 - Reply

    I used the scripts to successfully create a share on a remote server using a local group from that remove servers. To do so, I specified the domain name as the server name.

    This was on a win2008 r2 box.

  17. Chris April 11, 2011 at 13:50 - Reply

    Did you ever write Part 2?

  18. Chris Smith June 14, 2011 at 3:30 - Reply

    I have made a change to my script that adds a way to modify existing share permissions.

    #Start the Text for the message.
    $text = “$ShareName ($FolderPath): ”
    #Package the SecurityDescriptor via the New-SecurityDescriptor Function.
    $SecDesc = New-SecurityDescriptor $ACEs

    #Check to see if the share already exists – This is to modify Permissions
    $CheckShare = (Get-WmiObject Win32_Share -comp $Computername -Filter “Name=’$ShareName'”)
    if ($CheckShare -ne $null) {
    # “Share exists and will now be modified!!!”
    $result = $CheckShare | foreach-object { $_.SetShareInfo(0, $Description, $SecDesc) }

    I hope this helps other people use your script.

    • Jakob Gottlieb Svendsen
      Jakob Gottlieb Svendsen June 14, 2011 at 10:59 - Reply

      Hi Chris!

      I was actually working on part 2, but i had to do work instead! .. thanks alot for your script.
      It is pretty cool that powershell 2.0 has the New-SecurityDescriptor, which didnt exist when i wrote this blog post 🙂

      although i havent tested, i would guess that your script replace all exiting permissions, i might use it in a part 2, makin it able to add them to the exiting.

      Or am i wrong? 🙂

      • Tom December 18, 2012 at 16:18 - Reply

        Jakob,

        Could you explain this code that Chris added? I am putting it in but I am not having any luck. I am also not programmer. I am trying to learn Powershell and only a year into it. What I am trying to do is set permissions on a share.

        • Jakob Gottlieb Svendsen
          Jakob Gottlieb Svendsen December 19, 2012 at 11:01 - Reply

          please look at Rudy’s great example below. I think that does the job for you

          • Tom December 19, 2012 at 20:51

            Ok, been trying to with no luck so far. But you think that will allow me to set the permissions periodically? My end goal is to create a share with the right accounts, which is what your script does for me. The second part is that I want the script to re-apply the permissions if they have changed.

          • Tom December 19, 2012 at 22:56

            Ok, got it to work and it is beautiful. Could you suggest a way to remove all users from a share? While this script re-adds people if they were removed, lets say someone adds the Everyone group. This script will not remove everyone. So I am thinking if I could have the script run to remove all groups, then the section to add the group I want it would be great.

  19. David Daniels June 22, 2011 at 19:33 - Reply

    To add local groups from the remote computer I added an addition modified function and performed a call appropriately.

    Function New-ACELocal (
    [string] $Name = (Write-Host “Please provide user/group name”),
    [string] $Permission = “Read”,
    [string] $ComputerName = “.”,
    [switch] $Group = $false)
    { $Trustee = ([WMIClass] “\$ComputerNamerootcimv2:Win32_Trustee”).CreateInstance()
    if (!$group) { $account = [WMI] “\$ComputerNamerootcimv2:Win32_Account.Name=’$Name’,Domain=’$ComputerName'” }
    else
    { $account = [WMI] “\$ComputerNamerootcimv2:Win32_Group.Name=’$Name’,Domain=’$ComputerName'”}
    $accountSID = [WMI] “\$ComputerNamerootcimv2:Win32_SID.SID=’$($account.sid)'”
    $Trustee.Domain = $Domain
    $Trustee.Name = $Name
    $Trustee.SID = $accountSID.BinaryRepresentation
    $ACE = ([WMIClass] “\$ComputerNamerootcimv2:Win32_ACE”).CreateInstance()
    switch ($Permission) {
    “Read” { $ACE.AccessMask = 1179817 }
    “Change” { $ACE.AccessMask = 1245631 }
    “Full” { $ACE.AccessMask = 2032127 }
    default { Write-Host “$Permission is not a supported permission value. Possible values are ‘Read’,’Change’,’Full'” }}
    $ACE.AceFlags = 3
    $ACE.AceType = 0
    $ACE.Trustee = $Trustee
    return $ACE}

    $ACE2 = New-ACELocal -Name “Administrators” -ComputerName “$Repository” -Permission “Full” -Group

    • kiran February 24, 2012 at 20:21 - Reply

      function new-acelocal is not working for Administrators or any local group.

      Cannot convert value “\host1rootcimv2:Win32_Group.Name=’Administrators’,Domain=’host1’” to type “System.Management.ManagementObject”. Error: “Invalid pa
      rameter ”
      At C:UsersTEMPAppDataLocalTemp5867c7417-4389-4f78-a564-90bac98ab8d6.ps1:123 char:20
      + { $account = [WMI] <<<< “\$ComputerNamerootcimv2:Win32_Group.Name=’$Name’,Domain=’$ComputerName’”}
      + CategoryInfo : NotSpecified: (:) [], RuntimeException
      + FullyQualifiedErrorId : RuntimeException

  20. Alvaro Rodrigues February 13, 2012 at 17:34 - Reply

    I’ve try to use the script and i get the error:

    The term ‘Throw’ is not recognized as the name of a cmdlet, function, script file, or operable program. Check the spelling of the name, or if a path was included, verify that the path is correct and try again.
    At E:SistemaScriptsShareFunctions.psm1:122 char:29
    + [string] $ShareName = (Throw <<<< "Please provide the Share Name"),
    + CategoryInfo : ObjectNotFound: (Throw:String) [], CommandNotFoundException
    + FullyQualifiedErrorId : CommandNotFoundException

    I change throw to read-host and works! Why throw can't be works?

    Thanks! (Sorry by english. Im brazilian).

  21. eXo May 3, 2012 at 12:19 - Reply

    Thanks a lot for your work, guys!
    For those who copy&paste script gets errors like
    “Cannot convert value “\host1rootcimv2:Win32_Group.Name=’Administrators’,Domain=’host1’” to type ”System.Management.ManagementObject”. Error: “Invalid pa
    rameter ”
    At C:UsersTEMPAppDataLocalTemp5867c7417-4389-4f78-a564-90bac98ab8d6.ps1:123 char:20
    + { $account = [WMI] <<<< “\$ComputerNamerootcimv2:Win32_Group.Name=’$Name’,Domain=’$ComputerName’”}
    + CategoryInfo : NotSpecified: (:) [], RuntimeException
    + FullyQualifiedErrorId : RuntimeException"
    do not forget to find and replace ’ ” on the ' "

  22. Xavier Merlin May 21, 2012 at 9:43 - Reply

    Part2 any time “soon” ???

    • rudy devires June 21, 2012 at 16:53 - Reply

      Dear Xavier “the Wizard” Merlin, your name could be used for a x-men character

      Maybe this will help you:

      Function Set-SharePermission{

      param ([string]$Sharename, [string] $User)

      $strsid= ConvertTo-Sid $User $ADname
      $accountSID = [WMI] “Win32_SID.SID=’$($strsid.value)'”
      $t = ([WMIClass]”Win32_Trustee”).CreateInstance()
      $t.Domain =$ADname; $t.Name = $User; $t.SID =$accountSID.BinaryRepresentation
      #initialize ACE
      $ACE = ([WMIClass]”Win32_Ace”).CreateInstance()
      $ACE.AccessMask = 2032127; $ACE.AceFlags = 3; $ACE.AceType = 0; $ACE.Trustee = $t

      # Get SD for share
      $SD = (Get-WMIObject Win32_LogicalShareSecuritySetting -Filter “Name=’$Sharename'”).GetSecurityDescriptor().Descriptor
      # add new ace
      $SD.DACL+=$ACE.psobject.baseobject
      # put the share info
      Get-WMIObject Win32_Share -Filter “Name LIKE ‘$Sharename'” | %{
      $_.SetShareInfo(“”,””,$SD)
      }
      }
      function ConvertTo-Sid($UserName,$domain = $env:Computername) {

      $ID = New-Object System.Security.Principal.NTAccount($domain,$UserName)
      $SID = $ID.Translate([System.Security.Principal.SecurityIdentifier])
      $SID.Value
      }

  23. Greg Theron November 28, 2012 at 18:05 - Reply

    I can make the share but it will not add the Administrators Group? i get this error?
    Cannot convert value “\.rootcimv2:Win32_Group.Name=’Administrators’,Domain=’Domain'” to type “System.
    Management.ManagementObject”. Error: “Not found ”
    At C:SupportNew-APPS-Share.PS1:75 char:19
    + { $account = [WMI] <<<< "\$ComputerNamerootcimv2:Win32_Group.Name='$Name',Domain='$Domain'" }
    + CategoryInfo : NotSpecified: (:) [], RuntimeException
    + FullyQualifiedErrorId : RuntimeException

  24. Greg Theron November 28, 2012 at 18:07 - Reply

    Cannot convert value “\.rootcimv2:Win32_Group.Name=’Administrators’,Domain=’Domain'” to type “System.
    Management.ManagementObject”. Error: “Not found ”
    At C:SupportNew-APPS-Share.PS1:75 char:19
    + { $account = [WMI] <<<< "\$ComputerNamerootcimv2:Win32_Group.Name='$Name',Domain='$Domain'" }
    + CategoryInfo : NotSpecified: (:) [], RuntimeException
    + FullyQualifiedErrorId : RuntimeException

  25. Jakob Gottlieb Svendsen
    Jakob Gottlieb Svendsen November 28, 2012 at 18:16 - Reply

    Greg: there is no chance of me helping without more info. What OS? are you running as admin?

    thnx 🙂

    Xavior: sorry i have never done a follow up on this… no timeplan as we speak.

  26. Greg Theron November 28, 2012 at 18:32 - Reply

    We are running Server 2008 R2, i am logged in as administrator running Power Shell as administrator.

    i am trying to add the Administrators Group to a share.

    #Create ACE’s for the securitydescriptor for the share:
    #a group ACE, containing Group info, please notice the -Group switch
    $ACE = New-ACE -Name “Administrator” -Domain “My.domain” -Permission “Full”
    #a user ACE.
    $ACE2 = New-ACE -Name “Administrators” -Domain “My.domain” -Permission “Full” -Group

    Thanks for the Fast Responce

  27. Jon Almada July 2, 2013 at 21:40 - Reply

    I had to make a slight change in this script to allow it to work on Windows 2008

    At line 113 in the New-Share function:

    From

    $result = $Share.Create($FolderPath, $ShareName, 0, $false, $Description, $false , $SecDesc)

    To
    $result = $Share.Create($FolderPath, $ShareName, 0, 16777216 , $Description, $false , $SecDesc)

    This had to do with the number of connections allowed for the share and I set it to the default setting of 16777216 so that the share could be browsed once the share was created.

  28. Verdural May 9, 2014 at 14:37 - Reply

    Hi Jakob,

    Thanks for your great script.
    Who can i set the Cache to “No files or programs from the shared folder are available offline’?

    Thanks in advance,

    Regards,
    Verdural

  29. John-Rock Bilodeau July 14, 2014 at 16:36 - Reply

    Hi,

    I just wanted to thank you for your function. I used bits and pieces of it as well as a few other functions for creating shares and developed my own version. I built it the creation of share and building the security permissions all in one function that validate if an account is a user or group against AD or the specified computer. I just published it in the MS script gallery. Have a peek. hopefully it will help others.

    http://gallery.technet.microsoft.com/scriptcenter/Create-Shared-Folder-with-79fce495

  30. newel post austin texas September 8, 2014 at 5:07 - Reply

    newel post austin texas

    Coretech Blog » Blog Archive » Powershell – WMI: Working with Shares – Part 1: Creating a Share with Custom Permissions

  31. varapraveen December 30, 2015 at 7:36 - Reply

    when i ran the script,the user setting got set properly which i came to know after seeing the properties of the file which i tried to share.But when i tried to access the folder from the user which i granted,I am not able to access.

Leave A Comment