More PowerShell geekery ahead!
I've written about this before, here and here. But, I use it so often that I am constantly thinking about how to improve it. Well, today, I made what I feel is a major leap regarding the functionality of this tool.
The main goal of my efforts today was to make this tool more Powershell-y... that is, not so much a script to be run, but a function that now interacts with the pipeline and accepts parameters.
My previous version of this script was normally run dot-sourced and the session looked something like:
It required: 1)being run, 2)selecting <1 or 2>; 3)typing of foldername or .txt file path
It was basically a mini-app. This was OK, but not really in the spirit of Powershell. So, I re-wrote things. Actually, I re-organized things more than re-wrote them. Anyway, now the process looks like:
It is now a function. So, I can now perform this operation the following ways:
- 'folderName1','folderName2' | New-SharedFolder
- 'c:\scripts\folderList.txt' | New-SharedFolder
- 'folderName', 'c:\scripts\folderList.txt' | New-SharedFolder
- New-SharedFolder 'folderName'
- etc...
The function accepts input of a folder name and/or a filename (with path). It runs a Test-Path on the input and, if it finds the file, it reads its contents. If the Test-Path fails, it assumes that a folder name was entered.
Here's the new code, in case you are interested. I am sure there are many things in this code that some PoSH gurus out there might roll their eyes at. But, for me, it is a big leap forward. I know that I am not done working on this function.
function New-SharedFolder { param ( [string]$inputString ) BEGIN { # Usage Instructions function Usage() { <Code to display docs> } # Loads the foldernames in array for processing function load_folderlist_array { param ( [string]$inStr ) if (Test-Path $inStr) { $fl = Get-Content $inStr } else { $fl = $inStr } return $fl } # Displays help if (($Args[0] -eq "-?") -or ($Args[0] -eq "-help")) { Usage break } # This Function creates folder and groups function process_folders { param([array]$allFolderNames) foreach ($folder in $allFolderNames) { Write-Host "************************************************" -foregroundcolor White Write-Host "Now processing folder name: $folder" # Defining path to folder $FullPath = "\\FS01\Groups\" + $folder #Does this folder already exist? if (Test-Path $FullPath) { #Folder already exists. Abort operation. Write-Host -ForegroundColor Red "The folder $FullPath already exists and is being skipped. Please verify the folder name." } else { # Create variables holding group names and descriptions # If necessary, shorten folder name to 13 characters if ($folder.length -gt 13) { $MODgroup = "s_$($folder.substring(0,13))_MOD" $MODdesc = "$folder -- MODify security group" $ROgroup = "s_$($folder.substring(0,13))_RO" $ROdesc = "$folder -- ReadOnly security group" } else { $MODgroup = "s_$($folder)_MOD" $MODdesc = "$folder -- MODify security group" $ROgroup = "s_$($folder)_RO" $ROdesc = "$folder -- ReadOnly security group" } # Defines OU location for Security Group Creation $GroupContainer = <Path to OU> # Create Groups Write-Host "Creating MODify security group for this folder..." -NoNewline $null = New-QADGroup -ParentContainer $GroupContainer -name $MODgroup -samAccountName $MODgroup -GroupType 'security' -GroupScope 'GLOBAL' -description $MODdesc Write-Host " DONE!" -foregroundcolor Green Write-Host "Creating ReadOnly security group for this folder..." -NoNewline $null = New-QADGroup -ParentContainer $GroupContainer -name $ROgroup -samAccountName $ROgroup -GroupType 'security' -GroupScope 'GLOBAL' -description $ROdesc Write-Host " DONE!" -foregroundcolor Green # Create Folder Write-Host "Creating folder under \\FS01\Groups ..." -NoNewline $null = New-Item -path \\FS01\Groups -name $folder -type directory Write-Host " DONE!" -foregroundcolor Green # Check for security groups on all DCs wait_for_replication # Assign rights to the folder for the groups # MODIFY RIGHTS Write-Host "`nAssigning MODify ACL entries for this folder to the MOD group..." assign_rights "Modify" $MODgroup # READONLY RIGHTS Write-Host "Assigning ReadOnly ACL entries for this folder to the RO group..." assign_rights "Read" $ROgroup } } } # Checks all DCs for security groups, verifying replication function wait_for_replication { $DCs = Get-QADComputer -ComputerRole DomainController foreach ($DC in $DCs) { $aa = $null $bb = $null Write-Host "`nChecking for Security Group on $($DC.Name)" -noNewLine do { $null = Connect-QADService -Service $DC.Name $aa = Get-QADGroup $MODgroup $bb = Get-QADGroup $ROgroup Disconnect-QADService Start-Sleep -Seconds 1 Write-Host '.' -noNewLine } until ($aa -ne $null -and $bb -ne $null) } } # Modifies ACL on folder, giving MOD and RO groups appropiate rights function assign_rights { param([string]$Rights, [string]$GroupName) $acl = get-acl $FullPath $Inherit = [Security.AccessControl.InheritanceFlags] "ContainerInherit, ObjectInherit" $Prop = [Security.AccessControl.PropagationFlags] "None" $NewRule = new-object Security.AccessControl.FileSystemAccessRule $GroupName, $Rights, $Inherit, $Prop, Allow $modified = $FALSE $modded = $acl.ModifyAccessRule("Add", $NewRule, [ref]$modified) set-acl -path $FullPath -AclObject $acl if ($modded) { Write-Host "ACL for $GroupName successfully applied." -foregroundcolor Green } else { Write-Host "WARNING!!! ACL for $GroupName failed to apply!" -ForegroundColor Red } } } PROCESS { if ($inputString -and $_) { Throw 'Please use either pipeline or input parameter' break } elseif ($inputString) { $folderNames = load_folderlist_array $inputString } elseif ($_) { $folderNames = load_folderlist_array $_ } else { Usage break } process_folders $folderNames } END { Write-Host "`nJob Complete." -foregroundcolor White } }

0 comments:
Post a Comment