Hi, all! I'm having multiple problems with my first script I've written with Powershell. The script below does the following:
1. Prompts the user for a corporate division under which a shared folder will be created, and adjusts variables accordingly.
2. Prompts if the folder will be a global folder or an office/location-specific folder, and makes appropriate adjustments to variables.
3. If a global folder, prompts for the name. If an office/location-specific folder, prompts for each component of the street address, city and state and an optional modifier. I've prompted for this information in this way because the information is used differently later on in the script.
4. Verifies the entered information and requests confirmation to proceed.
5. Creates the folder.
6. Creates an AD OU and/or security group(s).
7. Applies appropriate security groups to the new folder and removes undesired permissions.
Import-Module ActiveDirectory $Division = "" $DivAbbr = "" $OU = "" $OUDrive = "AD:\" $FolderName = "" $OUName = "" $GroupName = "" $OURoot = "ou=DFS Restructure Testing OU,ou=Pennsylvania Camp Hill 4410 Industrial Park Rd,ou=Locations,ou=Camp Hill,dc=jacobsonco,DC=com" $FSRoot = "E:\" $FolderPath = "" $DefaultFolders = "Archive","Customer Service","Equipment","Inbounds","Management","Outbounds","Processes","Projects","Quality","Reports","Returns","Safety","Schedules","Time Keeping","Training" [bool]$Location = 0 do { $userInput = Read-Host "Enter CLS Division: (W)arehousing, (S)taffing, or (P)ackaging" Switch ($userInput) { W {$Division = "Warehousing"; $DivAbbr = "WHSE"; $OU = "ou=Warehousing,"; break} S {"Staffing is not yet implemented."; break} P {"Packaging is not yet implemented."; break} default {"Invalid choice. Please re-enter."; break} } } while ($DivAbbr -eq "") write-host "" write-host ($Division + " was selected.") $FolderPath = $Division + "\" write-host "" $choice = "" do { $choice = Read-Host "Will this be a (G)lobal folder or (L)ocation folder?" Switch ($choice) { G {$Location = $false; break} L {$Location = $true; $FolderPath = $FolderPath + "Locations\"; $OU = "ou=Locations," + $OU; break} default {"Invalid choice. Please re-enter."; $choice = ""; break} } } while ($choice -eq "") write-host "" write-host ("Location is set to: " + $Location) write-host "" if ($Location -eq $false) { $FolderName = Read-Host "Please enter folder name:" $GroupName = $DivAbbr + " " + $FolderName } else { $input = Read-Host "Please enter two-letter state abbreviation:" $FolderName = $FolderName + $input + " " $input = Read-Host "Please enter city:" $FolderName = $FolderName + $input + " " $input = Read-Host "Please enter street address number only:" $FolderName = $FolderName + $input $GroupName = $DivAbbr + " " + $FolderName $FolderName = $FolderName + " " $input = Read-Host "Please enter street name:" $FolderName = $FolderName + $input $input = Read-Host "Please enter any optional information to appear in folder name:" if ($input -ne "") { $FolderName = $FolderName + " " + $input } $OUName = $FolderName } write-host write-host "Path for folder: "$FSRoot$FolderPath$FolderName write-host "AD Path: "$OUDrive$OU$OURoot write-host "New OU Name: "$OUName write-host -NoNewLine "New Security Group names: "$GroupName if ($Location -eq $true) { write-host " and "$GroupName" MGMT" } write-host $input = Read-Host "Please confirm creation of new site/folder: (Y/N) " if ($input -ne "Y") { Exit } write-host write-host -NoNewLine "Folder exists: "; Test-Path ($FSRoot + $FolderPath + $FolderName) if (Test-Path ($FSRoot + $FolderPath + $FolderName)) { Write-Host "Folder already exists! Skipping folder creation..." } else { write-host "Folder does not exist. Creating..." new-item -path ($FSRoot + $FolderPath) -name $FolderName -itemtype directory Set-Location ($FSRoot + $FolderPath + $FolderName) } if ($Location -eq $true) { $tempOUName = "ou=" + $OUName + "," write-host write-host $OUDrive$tempOUName$OU$OURoot write-host write-host -NoNewLine "OU exists: "; Test-Path ($OUDrive + $tempOUName + $OU + $OURoot) if (Test-Path ($OUDrive + $tempOUName + $OU + $OURoot)) { Write-Host "OU already exists! Skipping OU creation..." } else { write-host "OU does not exist. Creating..." New-ADOrganizationalUnit -Name $OUName -Path ($OU + $OURoot) -ProtectedFromAccidentalDeletion $false $GroupNameMGMT = $GroupName + " MGMT" if (!(Test-Path ($OUDrive + "CN=" + $GroupName + "," + $tempOUName + $OU + $OURoot))) { write-host "Normal user group does not exist. Creating..."; New-ADGroup -Name $GroupName -GroupCategory Security -GroupScope Global -Path ("OU=" + $OUName + "," + $OU + $OURoot)} if (!(Test-Path ($OUDrive + "CN=" + $GroupNameMGMT + "," + $tempOUName + $OU + $OURoot))) { write-host "Management user group does not exist. Creating..."; New-ADGroup -Name $GroupNameMGMT -GroupCategory Security -GroupScope Global -Path ("OU=" + $OUName + "," + $OU + $OURoot)} } $FolderACL = get-acl ($FSRoot + $FolderPath + $FolderName) $FolderACL.SetAccessRuleProtection($True,$True) # $FolderACL.Access | where {$_.IdentityReference -eq "BUILTIN\Users"} | %{$FolderACL.RemoveAccessRuleAll($_)} $BIUsers = New-Object System.Security.Principal.NTAccount("BUILTIN\Users") $BIUsersSID = $BIUsers.Translate([System.Security.Principal.SecurityIdentifier]) write-host $BIUsersSID.Value # out-string -inputObject $BIUsers $Ar = New-Object System.Security.AccessControl.FileSystemAccessRule($BIUsersSID.Value,"ReadAndExecute,AppendData,CreateFiles,Synchronize","ContainerInherit, ObjectInherit", "None", "Allow") $FolderACL.RemoveAccessRuleAll($Ar) Set-ACL ($FSRoot + $FolderPath + $FolderName) $FolderACL get-acl ($FSRoot + $FolderPath + $FolderName) | fl $FolderACL = get-acl ($FSRoot + $FolderPath + $FolderName) $ADGroupName = "JACOBSON\" + $GroupName $objUser = New-Object System.Security.Principal.NTAccount($ADGroupName) $objUser.Translate([System.Security.Principal.SecurityIdentifier]).Value write-host $ADGroupName write-host $objUser.Value $Ar = New-Object System.Security.AccessControl.FileSystemAccessRule($ADGroupName,"ReadAndExecute","ContainerInherit, ObjectInherit", "None", "Allow") Out-String -InputObject $ar $FolderACL.AddAccessRule($Ar) $ADGroupName = "JACOBSON\" + $GroupNameMGMT $Ar = New-Object System.Security.AccessControl.FileSystemAccessRule($ADGroupName, "Modify", "ContainerInherit, ObjectInherit", "None", "Allow") Out-String -InputObject $ar $FolderACL.AddAccessRule($Ar) Set-ACL ($FSRoot + $FolderPath + $FolderName) $FolderACL } else { $tempOUName = "cn=" + $GroupName + "," write-host write-host $OUDrive$tempOUName$OU$OURoot write-host write-host -NoNewLine "Group exists: "; Test-Path ($OUDrive + $tempOUName + $OU + $OURoot) if (Test-Path ($OUDrive + $tempOUName + $OU + $OURoot)) { Write-Host "Security group already exists! Skipping new security group creation..." } else { write-host "Security group does not exist. Creating..." New-ADGroup -Name $GroupName -GroupCategory Security -GroupScope Global -Path ($OU + $OURoot) } $FolderACL = get-acl ($FSRoot + $FolderPath + $FolderName) $ADGroupName = "JACOBSON\" + $GroupName $FolderACL.SetAccessRuleProtection($True,$True) $Ar = New-Object System.Security.AccessControl.FileSystemAccessRule($ADGroupName,"Modify","ContainerInherit, ObjectInherit", "None", "Allow") $FolderACL.AddAccessRule($Ar) $FolderACL.Access | where {$_.IdentityReference -eq "BUILTIN\Users"} | %{$FolderACL.RemoveAccessRuleAll($_)} Set-ACL ($FSRoot + $FolderPath + $FolderName) $FolderACL }
My problems right now are in the assignment/removal of security groups on the newly-created folder, and the problems are two-fold. Yes, I am running this script as an Administrator.
First, I am unable to remove the BUILTIN\Users group from the folder when this is an office/location-specific folder. I've tried to remove the group in several different ways, and none are having any effect. Oddly, if I type in the lines directly into Powershell, they work as expected. I've tried the following methods:
$FolderACL = get-acl ($FSRoot + $FolderPath + $FolderName) $FolderACL.SetAccessRuleProtection($True,$True) $FolderACL.Access | where {$_.IdentityReference -eq "BUILTIN\Users"} | %{$FolderACL.RemoveAccessRuleAll($_)} Set-ACL ($FSRoot + $FolderPath + $FolderName) $FolderACL
$FolderACL = get-acl ($FSRoot + $FolderPath + $FolderName) $FolderACL.SetAccessRuleProtection($True,$True) $BIUsers = New-Object System.Security.Principal.NTAccount("BUILTIN\Users") $BIUsersSID = $BIUsers.Translate([System.Security.Principal.SecurityIdentifier]) $Ar = New-Object System.Security.AccessControl.FileSystemAccessRule($BIUsersSID.Value,"ReadAndExecute,AppendData,CreateFiles,Synchronize","ContainerInherit, ObjectInherit", "None", "Allow") $FolderACL.RemoveAccessRuleAll($Ar) Set-ACL ($FSRoot + $FolderPath + $FolderName) $FolderACL
In the first case, the script goes through and has no apparent effect because afterwards, I do a get-acl and the BUILTIN\Users group is still there, although when looking through the GUI, inheritance appears to have been broken from the parent folder.
In the second case, I get the following error message:
Exception calling "RemoveAccessRuleAll" with "1" argument(s): "Some or all identity references could not be translated."At C:\Users\tesdallb\Documents\FileServerBuild.ps1:110 char:5
+ $FolderACL.RemoveAccessRuleAll($Ar)
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : NotSpecified: (:) [], MethodInvocationException
+ FullyQualifiedErrorId : IdentityNotMappedException
This seems strange that the local server is unable to translate the SID of a BUILTIN account. I've also tried explicitly putting in the BUILTIN\Users SID in place of the variable in the New-Object line, but that gives me the same error. I've also tried the solutions given in this thread: http://social.technet.microsoft.com/Forums/windowsserver/en-US/ad59dc58-1360-4652-ae09-2cd4273cbd4f/remove-acl-issue?forum=winserverpowershell and at this URL:http://technet.microsoft.com/en-us/library/ff730951.aspx but these solutions also failed to have any effect.
My second problem is when I try to apply the newly-created security groups, I also will get the "Some or all identity references could not be translated." I thought I had found a workaround to the problem by adding the -PassThru option to the New-ADGroup commands, because it would output the SID of the group after creation, however a few lines later, the server is unable to translate the account to apply the security groups to the folder.
My first Powershell script has been working well up to this point and now I seem to have hit a showstopper. Any help is appreciated.
Thanks!