Thanks Richard. It’s too bad that it wasn’t doable with CIM.
I ended up using some of the info in your example and some for an example i found on the Microsoft script gallery and came up with this.
<#
.Synopsis
To create a shared a folder on local or remote Computer.
.DESCRIPTION
To share a folder on local or remote Computer using WMI.
Access Type is Read by default.
Different Access can be set with the -Access Parameter.
The share is created with maximum number of connections by default, but can be changed with the -MaxConnection parameter.
If the Folder Path doesn't exist, this script will attempt to create it.
.PARAMETER ComputerName
Specifies the name of the local or remote computer(s) where you want to share a folder.
The default is the local Computer
.PARAMETER FolderPath
Specifies the path to the location of the folder to share. The path must be fully qualified; relative paths or paths that contain wildcard characters are not permitted.
This is a required parameter
.PARAMETER ShareName
Specifies a name for the new share.
This is a required parameter
.PARAMETER Description
Specifies an optional description of the new share.
The default value no description, or an empty description
.PARAMETER AccessType
The type of access that you wish to grant to for the user to the share.
Can be set to “Allow”, “Deny”.
Default is “Allow”
.PARAMETER Access
The share permision. Can be one of the set “None”,“Read”,“Modify”,“Full”.
Default is “Read”
.PARAMETER Users
Specifies which accounts are granted permission to the share
If adding a domain user make sure that the user is in the following format DOMAIN\Username
This is a required parameter
.PARAMETER MaxConnections
Specifies the maximum number of concurrently connected users that the new share may accommodate.
If this parameter is set to zero (0), then the number of users is unlimited.
The default value is zero (0).
.EXAMPLE
New-Share -FolderPath ‘C:\Temp’ -ShareName ‘Temp’ -Description ‘Test shared folder’ -AccessType Allow -Access Full -Users ‘Everyone’
Create a share named Temp for the C:\Temp folder with Allow Full control for the Everyone group
.EXAMPLE
New-Share -FolderPath ‘C:\Temp’ -ShareName ‘Temp’ -Description ‘Test shared folder’ -AccessType Deny -Access Full -Users ‘Everyone’
Create a share named Temp for the C:\Temp folder with Deny Full control for the Everyone group
.EXAMPLE
New-Share -ComputerName ‘MyServer’ -FolderPath ‘C:\Temp’ -ShareName ‘Temp’ -Description ‘Test shared folder’ -AccessType Deny -Access Full -Users ‘MyDomain\TestUser’
Create a share named Temp for the C:\Temp folder on a remote computer named MyServer, with Allow Full control for the The user named TestUser on the MyDomain domain.
.NOTES
This Function was written based on the example Set-LHSFileShare.ps1 found at http://gallery.technet.microsoft.com/scriptcenter/To-share-a-folder-or-ff92b3fb
and example provided by Richard Siddaway https://powershell.org/forums/topic/using-cim-to-create-a-shared-folder/
AUTHOR: John-Rock Bilodeau
LASTEDIT: 16/05/2014
KEYWORDS: Share, Foldershare
.INPUTS
System.String, you can pipe ComputerNames to this Function
.OUTPUTS
System.Boolean, True when the given folder could be shared.
.LINK
Create method of the Win32_Share class
http://msdn.microsoft.com/en-us/library/aa389393(v=vs.85).aspx
Win32_ACE class
http://msdn.microsoft.com/en-us/library/aa394063(v=vs.85).aspx
#>
function New-Share
{
[CmdletBinding()]
[OutputType([bool])]
Param
(
[Parameter(Position=0,Mandatory=$False,ValueFromPipeline=$True,
HelpMessage=‘An array of computer names. The default is the local computer.’)]
[string[]]$ComputerName = $Env:COMPUTERNAME,
[Parameter(Position=1, Mandatory=$false,HelpMessage="No folder path specified")]
[string]$FolderPath,
[Parameter(Position=2, Mandatory=$true,
HelpMessage="No share name specified")]
[string]$ShareName,
[Parameter(Position=3,HelpMessage="No description specified")]
[string]$Description,
[Parameter(Position=4)]
[ValidateSet('Allow','Deny','Audit')]
[String]$AccessType = "Allow",
[Parameter(Position=5)]
[ValidateSet('None','Read','Modify','Full')]
[String]$Access = "Read",
[Parameter(Position=6, Mandatory=$True)]
[String[]]$Users,
[Parameter(Position=7)]
[UInt32]$MaxConnections = 0
)
Begin
{
# Set the AccessMask
[UInt32]$AccessMask = Switch($Access) {
'None' {'1'}
'Read' {'1179817'}
'Modify' {'1245631'}
'Full' {'2032127'}
}
# Set the AceType
[UInt32]$AceTypeAccess = Switch($AceType) {
'Allow' {'0'}
'Deny' {'1'}
#'Audit' {'2'} possibly for future use
}
# Define the Ace Flag values
[UInt32]$ACEFLAG_OBJECT_INHERIT_ACE = 1
[UInt32]$ACEFLAG_CONTAINER_INHERIT_ACE = 2
[UInt32]$ACEFLAG_NO_PROPAGATE_INHERIT_ACE = 4
[UInt32]$ACEFLAG_INHERIT_ONLY_ACE = 8
[UInt32]$ACEFLAG_INHERITED_ACE = 16
[UInt32]$ACEFLAG_VALID_INHERIT_FLAGS = 31
[UInt32]$ACEFLAG_SUCCESSFUL_ACCESS_ACE_FLAG = 64
[UInt32]$ACEFLAG_FAILED_ACCESS_ACE_FLAG = 128
# Should almost always be 3. Really. don't change it.
[UInt32]$AceFlag = $ACEFLAG_OBJECT_INHERIT_ACE + $ACEFLAG_CONTAINER_INHERIT_ACE
# Set the ShareType
[String]$Type = 'Disk Drive'
# I simply listed all the share type to give me the flexibility to expand the function easily in the future.
[UInt32]$ShareType = switch($Type){
'Disk Drive' {'0'}
'Print Queue' {'1'}
'Device' {'2'}
'IPC' {'3'}
'Disk Drive Admin' {'2147483648'}
'Print Queue Admin' {'2147483649'}
'Device Admin' {'2147483650'}
'IPC Admin' {'2147483651'}
}
}
Process
{
# Loop through each Computer name specified
foreach($Computer in $ComputerName){
# Loop through each user
foreach($user in $Users){
# If username is specified in Domain\username format split it
if($User.Contains("\")){
$Domain = ($User -split "\\")[0]
$Username = ($User -split "\\")[1]
} else {
$Domain = $null
$Username = $User
}
# Create the Trustee on the specified computer
$Trustee = ([WMIClass] "\\$Computer\root\cimv2:Win32_Trustee").CreateInstance()
$Trustee.Name = $Username
$Trustee.Domain = $Domain
# Create the ACE on the specified computer
$Ace = ([WMIClass] "\\$Computer\root\cimv2:Win32_ACE").CreateInstance()
$Ace.AccessMask = $AccessMask
$Ace.AceFlags = $AceFlag
$Ace.AceType = $AceTypeAccess
$Ace.Trustee = $Trustee
# Create the Security Descriptor on the specified computer
$SD = ([WMIClass] "\\$Computer\root\cimv2:Win32_SecurityDescriptor").CreateInstance()
$SD.DACL = @()
$SD.DACL += $Ace.psObject.baseobject
# Check if the share exists on the specified computer
if (!(Get-WmiObject -Class Win32_Share -ComputerName $Computer -Filter "Name='$ShareName'"))
{
# Check if the directory exist at the specified path.
# If not create it
[String]$UncPath = "\\$Computer\$($FolderPath.Replace(':','$'))"
if(!(Test-Path -Path "$UncPath")){
New-Item -Path $UncPath -ItemType Directory | Out-Host $null
}
# Create the Share
$mc = [WmiClass]"\\$Computer\root\cimv2:Win32_share"
$InParams = $mc.psbase.GetMethodParameters("Create")
$InParams.Access = $SD
$InParams.Description = $Description
$InParams.MaximumAllowed = $MaxConnections
$InParams.Name = $ShareName
$InParams.Password = $null
$InParams.Path = $FolderPath
$InParams.Type = $ShareType
$Return = $Null
$Return = $mc.PSBase.InvokeMethod("Create", $InParams, $Null)
# Check if it was successfull
$rvalue = Switch ($Return.returnvalue) {
0 {"Success"}
2 {"Access Denied"}
8 {"Unknown Failure"}
9 {"Invalid Name"}
10 {"Invalid Level"}
21 {"Invalid Parameter"}
22 {"Duplicate Share"}
23 {"Redirected Path"}
24 {"Unknown Device or Directory"}
25 {"Net Name Not Found"}
Default {"Unknown Error"}
}
if ($Return.returnvalue -ne 0)
{
Write-Error ("Failed to create share {0} for {1} on {2}. Error: {3}" -f $ShareName,$FolderPath,$Computer,$rvalue)
Write-Output $False
}
else
{
Write-Host "Successfully shared folder [$FolderPath] on [$Computer] as [$ShareName] ."
Write-Output $True
}
} else {
Write-Error "The share $ShareName already exists on $Computer"
}
}
}
}
End
{
}