Note
Access to this page requires authorization. You can try signing in or changing directories.
Access to this page requires authorization. You can try changing directories.
Question
Wednesday, August 7, 2019 11:02 PM
The variable for the share was evaluated but the value of the variable represented by the share permissions was not. Is there a way to evaluate its value?
Grant-SmbShareAccess -Name $SHARE -AccessRight Read -AccountName $SHARERead
Grant-SmbShareAccess : Cannot validate argument on parameter 'Name'. The argument is null. Provide a valid value for the argument, and then try running the command again.
At line:1 char:36
+ Grant-SmbShareAccess -Name $SHARE -AccessRight Read -AccountN ...
+ ~~~~~~
+ CategoryInfo : InvalidData: (:) [Grant-SmbShareAccess], ParameterBindingValidationException
+ FullyQualifiedErrorId : ParameterArgumentValidationError,Grant-SmbShareAccess
All replies (19)
Wednesday, August 21, 2019 6:05 PM ✅Answered
Again I warn you that we don't add user accounts to a share. We add groups then add the users to the group.
In a domain we set a share to Everyone FullControl and set the underlying folder permissions to the most restrictive level needed usually read/traverse and then carefully set permissions on the target folders.
Any other method will not provide decent security or ease of management. I suggest reading any of the numerous books on how to set up NT securely. This is a startin place for all techs working in a secure environment.
Without a full understanding of how Windows is designed to support secure file access almost anything you invent will not give you an optimal and secure system.
Aside from that there is really no way to follow your question. It is vague. I recommend contacting someone certified in the NT file system or a certified consultant to help you sort this out. Security is critical today more than ever and should be addressed by fully trained techs.
As for your last question - there is not enough information to address this. I suggest opening new topic with a clear description with examples. The new question has nothing to do with the original topic.'
\(ツ)_/
Wednesday, August 7, 2019 11:32 PM
Please read the error message carefully. It tells you the exact issue.
There is no evaluation here. You have a mistake and need to fox it. The error tells you that.
\(ツ)_/
Thursday, August 8, 2019 2:51 AM
Hi,
Thanks for your question.
Please try to post your code about how to define the variable $share for better help.
Best regards,
Lee
Just do it.
Thursday, August 8, 2019 6:07 PM
My code after assistance from jrv Consultant:
For($i=0; $i -le 0 ;$i++)
{
$Rules = @(
@{'Account' = 'Nash\UTLPLN-NAS-PROD-RO'
'Permissions' = 'Traverse,Executefile,ListDirectory,ReadData,ReadAttributes,ReadExtendedAttributes,ReadPermissions,Synchronize'
'Inheritance'= 'ContainerInherit, ObjectInherit'
'ProPagation' = 'None'
'TyPe' = 'Allow'}
@{'Account' = 'Nash\UTLPLN-NAS-PROD-RW'
'Permissions' = 'Traverse,Executefile,ListDirectory,ReadData,ReadAttributes,ReadExtendedAttributes,CreateFiles,WriteData,CreateDirectories,APPendData,WriteAttributes,WriteExtendedAttributes,Delete,ReadPermissions,Synchronize'
'Inheritance' = 'ContainerInherit, ObjectInherit'
'ProPagation' = 'None'
'TyPe' = 'Allow'} )
#Initialize the variable values by reading them from the Hashtable.
$Config = Get-Content 'C:\Users\$jstrode\Documents\Config1.data'
$config = $Config | ForEach-Object {$_ -rePlace('\\','\\')}
$config = $config | ConvertFrom-StringData
$Server = $Config.("Server$i")
$PATH = $Config.("PATH$i")
$SHARE = $config.("SHARE$i")
$SHARERead = ($Config.("Read$i"))
$SHAREModify = ($Config.("Modify$i"))
$SHAREFullControl = ($Config.("FC$i"))
$Session = New-PSSession $Server -Port 5985
Invoke-Command -Session $Session -ArgumentList $PATH, $SHARE,$SHARERead,$SHAREModify,$SHAREFullControl,$Rules -ScriPtBlock {
Param($PATH,$SHARE,$SHARERead,$SHAREModify,$SHAREFullControl,$Rules)
$P= $PATH.LastIndexOf('\')
IF(!($P -eq 2))
{
$Root = $PATH.Substring(0,$P)
}
Else
{
$Root = $PATH.Substring(0,$P).Replace(':',':\')
}
$Name = $PATH.Substring($P).TrimStart('\')
## Create Folder
IF (!(test-PATH $PATH))
{
write-host "Creating folder: " $PATH -ForegroundColor green
New-Item -Name $Name -PATH $Root -ItemTyPe Directory
}
else
{
write-host "The folder already exists: "$PATH -ForegroundColor Yellow
}
##Create SMB SHARE
Try{
#Get-SmbShare $share
IF (!(Get-SmbShare -Name $SHARE -ErrorAction SilentlyContinue))
{
write-host "Creating SHARE: " $SHARE -ForegroundColor green
New-SmbShare -Name $SHARE -PATH $PATH -Description "Test Shared Folder" -ReadAccess $SHARERead -ChangeAccess $SHAREModify -FullAccess $SHAREFullControl
}
Else
{
Write-OutPut "The SHARE already exists: " $SHARE
}
}
Catch
{
$ErrorMessage = $_.ExcePtion.Message
$FailedItem = $_.ExcePtion.ItemName
}
## Set NTFS Permissions on SHARE Folder
foreach($P in $Rules)
{
$ACL = Get-ACL $PATH
$ACE = New-Object System.Security.AccessControl.FileSystemAccessRule( $($P.Account),$($P.Permissions),$($P.Inheritance),$($P.Propagation),$($P.Type))
$ACL.AddAccessRule($ACE)
$ACL | Set-ACL $PATH
}
}
Get-PSSession | Remove-PSSession
}
Can the value of the Parameters in New-SMBShare be represented by Variables?
New-SmbShare -Name $SHARE -PATH $PATH -Description "Test Shared Folder" -ReadAccess $SHARERead -ChangeAccess $SHAREModify -FullAccess $SHAREFullControl
When I run the script no errors are generated but no additional entries are added to the default Share permissions.
When I substitute discrete values then these are added to the share permissions.
New-SmbShare -Name $SHARE -PATH $PATH -DescriPtion "Test Shared Folder" -ReadAccess "Everyone","Nash\USWF-DEV-ANNEX-MASNAC" -ChangeAccess "Authenticated Users" -FullAccess "administrators"
Thursday, August 8, 2019 6:20 PM
All Commands can take variables for parameter values.
Also your code completely misses the point I made with my posts. You do not need to do all of that.
Also the folder your are setting the perms on is NOT a share it is the shared folder. We usually set the share in a domain to "Everyone FullControl" which then requires us to correctly manage the permissions on all folders.
There is really no need to do any of what you are doing. Just place the name=value pairs into a file and read the file into a hash.
help Import-StringData -online. You should always avoid using temporary variables. Use the hash directly.
You can send the hash as a single argument.
You are writing almost 10 times as many lines of code that is needed. You also do nt need to use remoting. Just get the folder remotely using "Get-Item"
\(ツ)_/
Monday, August 12, 2019 4:25 PM
Thanks for the advice.
Monday, August 12, 2019 4:47 PM
Here is a cleaner approach to writing your code. The code still has many issues that you will need to address but this will make it easier to debug and understand. It also removes the redundancy in most places. Part of what is missing is wht is actually in your config file.
$sb = {
Param($PATH, $SHARE, $SHARERead, $SHAREModify, $SHAREFullControl)
$Rules = @(
@{
Account = 'Nash\UTLPLN-NAS-PROD-RO'
Permissions = 'Traverse,Executefile,ListDirectory,ReadData,ReadAttributes,ReadExtendedAttributes,ReadPermissions,Synchronize'
Inheritance = 'ContainerInherit, ObjectInherit'
Propagation = 'None'
Type = 'Allow'
},
@{
Account = 'Nash\UTLPLN-NAS-PROD-RW'
Permissions = 'Traverse,Executefile,ListDirectory,ReadData,ReadAttributes,ReadExtendedAttributes,CreateFiles,WriteData,CreateDirectories,APPendData,WriteAttributes,WriteExtendedAttributes,Delete,ReadPermissions,Synchronize'
Inheritance = 'ContainerInherit, ObjectInherit'
Propagation = 'None'
Type = 'Allow'
}
)
$P = $PATH.LastIndexOf('\') #'
IF (!($P -eq 2)) {
$Root = $PATH.Substring(0, $P)
}else{
$Root = $PATH.Substring(0, $P).Replace(':', ':\')
}
$Name = $PATH.Substring($P).TrimStart('\')
## Create Folder
IF (!(test-PATH $PATH)) {
write-host "Creating folder: " $PATH -ForegroundColor green
New-Item -Name $Name -PATH $Root -ItemTyPe Directory
} else {
write-host "The folder already exists: "$PATH -ForegroundColor Yellow
}
##Create SMB SHARE
Try {
IF (!(Get-SmbShare -Name $SHARE -ErrorAction SilentlyContinue)) {
write-host "Creating SHARE: " $SHARE -ForegroundColor green
New-SmbShare -Name $SHARE -PATH $PATH -Description "Test Shared Folder" -ReadAccess $SHARERead -ChangeAccess $SHAREModify -FullAccess $SHAREFullControl
} Else {
Write-OutPut "The SHARE already exists: " $SHARE
}
}
Catch {
$ErrorMessage = $_.ExcePtion.Message
$FailedItem = $_.ExcePtion.ItemName
}
## Set NTFS Permissions on SHARE Folder
foreach ($P in $Rules) {
$ACL = Get-ACL $PATH
$ACE = New-Object System.Security.AccessControl.FileSystemAccessRule($($P.Account), $($P.Permissions), $($P.Inheritance), $($P.Propagation), $($P.Type))
$ACL.AddAccessRule($ACE)
$ACL | Set-ACL $PATH
}
}
$config = Get-Content "C:\Users\$jstrode\Documents\Config1.data" | ForEach-Object{ $_ -replace ('\\', '\\') }
$config = $config | ConvertFrom-StringData
For ($i = 0; $i -le 0; $i++) {
$Arglist =@(
$config.("PATH$i")
$config.("SHARE$i")
$config.("Read$i")
$config.("Modify$i")
$config.("FC$i")
)
Invoke-Command -ComputerName $config.("Server$i") -ScriptBlock $sb -ArgumentList $arglist
}
\(ツ)_/
Monday, August 12, 2019 5:03 PM
I would also recommend that a CSV file would be best for your config data as it works like an array where string data requires unique names. Using a CSV would simplify this.
Import-Csv $configFile |
ForEach-Object{
$arglist = $_.PATH, $_.SHARE, $_.Read, $_.Modify, $_.FC
Invoke-Command -ComputerName $_.Server -ScriptBlock $sb -ArgumentList $arglist
}
Code design is the most important step in writing a complex script.
\(ツ)_/
Monday, August 12, 2019 5:09 PM
I can also suggest that you can simplify more by not using remoting. The SMB Cmdlets do their own remoting. The root folders can be easily accessed via the share once it is created or can be managed via the ADMIN share for the drive. This is sim pler and less prone to error.
\(ツ)_/
Monday, August 12, 2019 5:25 PM
Thank you for the code above. In my hands it generated two types of errors. No changes to the code you presented were made. I've seen each of these errors before.
The folder already exists: C:\Test0
Creating SHARE: C_APPS
No mapping between account names and security IDs was done.
+ CategoryInfo : NotSpecified: (MSFT_SMBShare:ROOT/Microsoft/Windows/SMB/MSFT_SMBShare) [New-SmbShare], CimException
+ FullyQualifiedErrorId : Windows System Error 1332,New-SmbShare
+ PSComputerName : ITO16027.NASH.COM
Exception calling "AddAccessRule" with "1" argument(s): "Some or all identity references could not be translated."
+ CategoryInfo : NotSpecified: (:) [], MethodInvocationException
+ FullyQualifiedErrorId : IdentityNotMappedException
+ PSComputerName : ITO16027.NASH.COM
Exception calling "AddAccessRule" with "1" argument(s): "Some or all identity references could not be translated."
+ CategoryInfo : NotSpecified: (:) [], MethodInvocationException
+ FullyQualifiedErrorId : IdentityNotMappedException
+ PSComputerName : ITO16027.NASH.COM
Monday, August 12, 2019 5:32 PM
I get no errors if I do not try to add discrete share permissions.
$Session = New-CimSession -ComputerName $Config."Server$i" -Port 5985
IF (!(Get-SmbShare -Name $config."share$i" -ErrorAction SilentlyContinue -CimSession $Session ))
{
write-host "Creating SHARE: " 'C_APPS' -ForegroundColor green
New-SmbShare -Name$config.("SHARE$i") -PATH 'C:\Test0' -Description "Test Shared Folder" -CimSession $Session
}
Else
{
Write-OutPut "The SHARE already exists: " $config.("share$i")
}
I get the same errors for the SMB share if I try with following
New-SmbShare -Name $SHARE -PATH $PATH -Description "Test Shared Folder" -ReadAccess $SHARERead -ChangeAccess $SHAREModify -FullAccess $SHAREFullControl -CimSession $Session
Monday, August 12, 2019 5:50 PM
As I noted there are still many issues with the code. My example was only to show you how to design the code. You still have to debug what you have,
YOu have to solve the first issue before rying to understand the reamiing issue.
New-SmbShare requires "ErrorActionStop" to trigger the exception.
This is how the exceptions should be handled:
Try {
if(Get-SmbShare -Name $SHARE -ErrorAction SilentlyContinue) {
Write-OutPut "The SHARE already exists: $SHARE"
}else{
write-host "Creating SHARE: $SHARE" -ForegroundColor green
New-SmbShare -ErrorAction Stop -Name $SHARE -PATH $PATH -Description 'Test Shared Folder' -ReadAccess $SHARERead -ChangeAccess $SHAREModify -FullAccess $SHAREFullControl
}
## Set NTFS Permissions on SHARE Folder
foreach ($P in $Rules) {
$ACL = Get-ACL $PATH -ErrorAction Stop
$ACE = New-Object System.Security.AccessControl.FileSystemAccessRule($($P.Account), $($P.Permissions), $($P.Inheritance), $($P.Propagation), $($P.Type))
$ACL.AddAccessRule($ACE)
$ACL | Set-ACL $PATH -ErrorAction Stop
}
}
Catch {
$ErrorMessage = $_.ExcePtion.Message
$FailedItem = $_.ExcePtion.ItemName
}
THis way you will only get the first exception and not run-on exceptions caused by the first failure.
\(ツ)_/
Monday, August 12, 2019 6:02 PM
Also note that "$PATH" should be the local path and NOT a UNC path. This would further simplify your code.
Start by changing to a CSV and use the correct argument type.
This is all you need for a CSV:
# csv structure
Server,Path, Name Permissions,GroupAccount
System1,d:\folder1,MyShare,Modify,DOM\ModifyGroup
System2,d:\folder1,OtherShare,Read,DOM\ReadGroup
System3,d:\folder1,ShareMe,FullControl,DOM\FCGroup
The permissions field can take an list of permissions separated by a comma. By using this data format the whole thing becomes much easier. You can easily build the CSV in Excel.
When the share already exists then the code would just attempt to dd the new permissions specified in the line.
\(ツ)_/
Monday, August 12, 2019 6:20 PM
I also see that your share design is not domain ready. In a domain we set shares to be "FullControl" and set the root folder permissions to adjust access.
This simplifies the CSV and the New-SmbShare.
New-SmbShare -Name $Name -PATH $Path -Description 'Test Shared Folder' -FullAccess EveryOne
The "Permissions" would then be set on the root folder. This method is in line with Best Practices for security in a domain. Individual share permissions are for use in a workgroup because there is no WG-wide account groups.
\(ツ)_/
Monday, August 12, 2019 6:36 PM
This would be the best way to use a CSV to do this:
"Server","Share","Path","Account","Permissions","Inheritance","Propagation","Type"
"MyServer1","MyShare","C:\folder1","Nash\UTLPLN-NAS-PROD-RO","Traverse,Executefile,ListDirectory,ReadData,ReadAttributes,ReadExtendedAttributes,ReadPermissions,Synchronize","ContainerInherit, ObjectInherit","None","Allow"
"MyServer1","MyShare","C:\folder1","Nash\UTLPLN-NAS-PROD-RW","Traverse,Executefile,ListDirectory,ReadData,ReadAttributes,ReadExtendedAttributes,CreateFiles,WriteData,CreateDirectories,APPendData,WriteAttributes,WriteExtendedAttributes,Delete,ReadPermissions,Synchronize","ContainerInherit, ObjectInherit","None","Allow"
This makes the coding very simple.
\(ツ)_/
Tuesday, August 13, 2019 5:30 PM
JRV,
I've done some additional searching and testing. I've failed to set share permissions other than the default everything. Using the values directly from the hash failed.
[ABC12345.NASH.COM]: PS C:\Users\$jstrode> New-SmbShare -ErrorAction Stop -Name $SHARE -PATH $PATH -Description 'Test Shared Folder' -ReadAccess $Config."Read$i" -ChangeAccess $Config."Modify$i" <obtaining value directly from hash
No mapping between account names and security IDs was done.
+ CategoryInfo : NotSpecified: (MSFT_SMBShare:ROOT/Microsoft/Windows/SMB/MSFT_SMBShare) [New-SmbShare], CimException
+ FullyQualifiedErrorId : Windows System Error 1332,New-SmbShare
[ABC12345.NASH.COM]: PS C:\Users\$jstrode> $Config."Modify$i"
("NT AUTHORITY\Authenticated Users")
[ABC12345.NASH.COM]: PS C:\Users\$jstrode> $ShareModify
("NT AUTHORITY\Authenticated Users")
[ABC12345.NASH.COM]: PS C:\Users\$jstrode> $Config."Read$i"
("NT AUTHORITY\Everyone","NASH\USWF-DEV-ANNEX-MASNAC")
[ABC12345.NASH.COM]: PS C:\Users\$jstrode> $ShareRead
("NT AUTHORITY\Everyone","NASH\USWF-DEV-ANNEX-MASNAC")
Using the variables $ShareRead and $ShareModify also failed.
[ABC12345.NASH.COM]: PS C:\Users\$jstrode> New-SmbShare -ErrorAction Stop -Name $SHARE -PATH $PATH -Description 'Test Shared Folder' -ReadAccess $ShareRead -ChangeAccess $ShareModify
No mapping between account names and security IDs was done.
+ CategoryInfo : NotSpecified: (MSFT_SMBShare:ROOT/Microsoft/Windows/SMB/MSFT_SMBShare) [New-SmbShare], CimException
+ FullyQualifiedErrorId : Windows System Error 1332,New-SmbShare
However, putting in the values directly works.
[ABC12345.NASH.COM]: PS C:\Users\$jstrode> New-SmbShare -ErrorAction Stop -Name $SHARE -PATH $PATH -Description 'Test Shared Folder' -FullAccess ("ABC12345\administrator") -ReadAccess ("NT AUTHORITY\Everyone","ford\USWF-DEV-ANNEX-MASNAC") -ChangeAccess ("NT AUTHORITY\Authenticated Users")
Name ScopeName Path Description
C_APPS * C:\Test0 Test Shared Folder
[ABC12345.NASH.COM]: PS C:\Users\$jstrode> Get-SmbShare
Name ScopeName Path Description
ADMIN$ * C:\Windows Remote Admin
C$ * C:\ Default share
C_APPS * C:\Test0 Test Shared Folder
IPC$ * Remote IPC
[ABC12345.NASH.COM]: PS C:\Users\$jstrode> Get-SmbShareaccess -Name C_APPS
Name ScopeName AccountName AccessControlType AccessRight
C_APPS * ITO16027\Administrator Allow Full
C_APPS * NT AUTHORITY\Authenticated Users Allow Change
C_APPS * Everyone Allow Read
C_APPS * NASH\USWF-DEV-ANNEX-MASNAC Allow Read
Any suggestions on how this process can be automated?
Tuesday, August 13, 2019 5:54 PM | 1 vote
A Share can only have Read/Modify/Full. Each account must be set separately.
As noted above shares should be set to "Everyone" "FullControl" and the root folder set to NTFS permissions. A share is not an NTFS object.
We should always start by setting the correct permissions on the root folder before creating the share. Once all folders are set correct then just create a default fullcontrol share and the NTFS permissions will be in control. This is how this is intended to work in domain. See the MS documentation.
\(ツ)_/
Wednesday, August 21, 2019 4:41 PM
I know that either using Invoke-Command or New-CimSession I can remotely add a group to a share.
Another wrinkle. I found different results for multiple users added remotely versus locally to a share locally. If I try to add using Invoke-Command or CimSession it fails with multiple users. If I use Enter-PSSession and run the command locally I can add multiple users to the share. I'm just curious as to why.
Wednesday, August 21, 2019 9:31 PM
I will do so. Sorry, I meant groups not users.
Thanks again.