none
Using variables for the arguments in the Grant-SMBShareAccess cmdlet RRS feed

  • שאלה

  • 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
     


    • נערך על-ידי John Strode יום רביעי 07 אוגוסט 2019 23:03
    יום רביעי 07 אוגוסט 2019 23:02

תשובות

  • 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.'


    \_(ツ)_/

    • סומן כתשובה על-ידי John Strode יום רביעי 21 אוגוסט 2019 21:31
    יום רביעי 21 אוגוסט 2019 18:05
    מנחה דיון

כל התגובות

  • 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.


    \_(ツ)_/

    יום רביעי 07 אוגוסט 2019 23:32
    מנחה דיון
  • 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.

    יום חמישי 08 אוגוסט 2019 02:51
    מנחה דיון
  • 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"

    יום חמישי 08 אוגוסט 2019 18:07
  • 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"


    \_(ツ)_/

    יום חמישי 08 אוגוסט 2019 18:20
    מנחה דיון
  • Thanks for the advice.
    יום שני 12 אוגוסט 2019 16:25
  • 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
    }


    \_(ツ)_/







    • נערך על-ידי jrvModerator יום שני 12 אוגוסט 2019 17:04
    יום שני 12 אוגוסט 2019 16:47
    מנחה דיון
  • 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.


    \_(ツ)_/

    יום שני 12 אוגוסט 2019 17:03
    מנחה דיון
  • 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.


    \_(ツ)_/

    יום שני 12 אוגוסט 2019 17:09
    מנחה דיון
  • 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

    יום שני 12 אוגוסט 2019 17:25
  • 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

    • נערך על-ידי John Strode יום שני 12 אוגוסט 2019 17:40 Additional information.
    יום שני 12 אוגוסט 2019 17:32
  • 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.


    \_(ツ)_/


    • נערך על-ידי jrvModerator יום שני 12 אוגוסט 2019 17:51
    יום שני 12 אוגוסט 2019 17:50
    מנחה דיון
  • 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.


    \_(ツ)_/



    • נערך על-ידי jrvModerator יום שני 12 אוגוסט 2019 18:03
    יום שני 12 אוגוסט 2019 18:02
    מנחה דיון
  • 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.


    \_(ツ)_/

    יום שני 12 אוגוסט 2019 18:20
    מנחה דיון
  • 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.


    \_(ツ)_/

    יום שני 12 אוגוסט 2019 18:36
    מנחה דיון
  • 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?

    יום שלישי 13 אוגוסט 2019 17:30
  • 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.  


    \_(ツ)_/

    יום שלישי 13 אוגוסט 2019 17:54
    מנחה דיון
  • 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.

    יום רביעי 21 אוגוסט 2019 16:41
  • 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.'


    \_(ツ)_/

    • סומן כתשובה על-ידי John Strode יום רביעי 21 אוגוסט 2019 21:31
    יום רביעי 21 אוגוסט 2019 18:05
    מנחה דיון
  • I will do so. Sorry, I meant groups not users.

    Thanks again.


    • נערך על-ידי John Strode יום רביעי 21 אוגוסט 2019 21:32 added more information
    יום רביעי 21 אוגוסט 2019 21:31