I'm trying to figure out a way to script in PowerShell the creation of multiple SMB shares on a file server with different share names pointing to different paths. What I mean is having a variable with share names I want to create and another variable to map those share names to their respective paths, example:
$ShareNames = "Share1","Share2","Share3"
$SharePaths = "C:\Temp1","C:\Temp2","C:\Temp3"
I want to be able to create the shares like so:
Share1 map to C:\Temp1
Share2 map to C:\Temp2
Share3 map to C:\Temp3
and so on...
I know the command to create the SMB shares, see below, but I can't figure out how to map each share name to it's appropriate path with multiple values in each variable.
$Parameters = @{
Name = $ShareName
ScopeName = "*"
Path = $SharePath
FolderEnumerationMode = "AccessBased"
CachingMode = "BranchCache"
ContinuouslyAvailable = $true
FullAccess = "Everyone"
}
New-SmbShare @Parameters
I've tried using foreach statements to accomplish what I'm looking to do but just can't seem to figure out how to do the 1 to 1 mapping of share names to share paths.
There are two approaches depending on your needs or likes.
for
If you want to stick with two variables being mapped to each other, you can use the for
statement.
But it's important to ensure both variables ($ShareNames
, $SharePaths
) are of type array
(at least when indexing into one) using the PS array subexpression operator @()
!
If they're not both of type array and one variable does only contain one string, the current index ($i
) of the for
iteration will be applied to an char
array ([char[]]'Share1'
), hence will only return the character at position of $i
('Share1'[0] → 'S'
rather than @('Share1')[0] → 'Share1'
).
To ensure/guarantee an array, read the comments in the code as there are two options:
for
statement using @()
@()
(mentioned as # alternative
comment in the code).#! ensure $ShareNames is an array with the array subexpression operator @()
$ShareNames = @('Share1', 'Share2', 'Share3')
#! ensure $SharePaths is an array with the array subexpression operator @()
$SharePaths = @('C:\Temp1', 'C:\Temp2', 'C:\Temp3')
for ($i = 0; $i -lt $ShareNames.Count; $i++) {
# try/finally to ensure no New-SmbShare gets executed in case of an error in splatting of $parameters
try {
$parameters = @{
Name = $ShareNames[$i] # alternative to ensure an array with "@($ShareNames)[$i]"
ScopeName = '*'
Path = $SharePaths[$i] # alternative to ensure an array with "@($SharePaths)[$i]"
FolderEnumerationMode = 'AccessBased'
CachingMode = 'BranchCache'
ContinuouslyAvailable = $true
FullAccess = 'Everyone'
}
New-SmbShare @parameters
} finally {}
}
foreach
No issues here with arrays and there is a clear mapping in the code.
We just need to use the .GetEnumerator()
method of the hash table in the foreach
statement.
$shares = @{
#key = value
'Share1' = 'C:\Temp1'
'Share2' = 'C:\Temp2'
'Share3' = 'C:\Temp3'
}
# we need to use the .GetEnumerator() method to iterate through the hash table
foreach ($share in $shares.GetEnumerator()) {
# try/finally to ensure no New-SmbShare gets executed in case of an error in splatting of $parameters
try {
$parameters = @{
Name = $share.Key
ScopeName = '*'
Path = $share.Value
FolderEnumerationMode = 'AccessBased'
CachingMode = 'BranchCache'
ContinuouslyAvailable = $true
FullAccess = 'Everyone'
}
New-SmbShare @parameters
} finally {}
}