# encoding: ascii # api: powershell # title: Set-DfsnForDR # description: See www.cosonok.com and Set-DfsnForDR.ps1. # version: 5.1 # type: function # author: vCosonok # license: CC0 # function: Pad-R # x-poshcode-id: 5495 # x-archived: 2014-10-11T09:30:14 # x-published: 2014-10-09T09:37:00 # # ######################################################### ## Set-DfsnForDR - v5.1 (September 2014) ## ## =================================================== ## ## CAVEAT UTILITOR! ## ## This program comes with no warranty and no support! ## ######################################################### $title = "Set-DfsnForDR - v5.1 (September 2014)" # TITLE $workingPath = $env:USERPROFILE # The users profile (where we expect the optional Set-DfsnForDR.ini to be) $domainServersFile = $workingPath + "\Set-DfsnForDR.ini" # This is the default file name and location for the DomainServersFile $backupPath = $workingPath + "\DFSN_BACKUP" # The default backup folder (where namespace backups go) ############################# # Generic Display Functions # ############################# Function Pad-R{ # Function Pad-R Param([string]$string,[int]$int) # Takes in a -string $string, and -int $int $string.PadRight($int," ").SubString(0,$int) # Pads it right to $padR with " " and cuts it down to size if it was too big to start with } # END of function Pad-R Function Columnize{ # Function Columnize $i = 0 # Initialize counter $i = 0 while($i -lt $args.count){ # While $i is less than the count of arguments Write-Host ((Pad-R $args[$i] $args[$i+1]) + " ") -F $args[$i+2] -NoNewline # Write to screen $args[i] adjusted to size $args[i], " ", and in color $args[$i+2], with no new line after $i += 3 # Accumulate count by 3 (since have sets of three arguments) } # END of while $i < count of arguments Write-Host # Starts a new line for the next row } # END of Columnize Function Wr-E{Write-Host} # Writes a Carriage Return (Enter) Function Wr-C{Write-Host ($args[0]) -F Cyan} # Writes supplied argument text in Cyan Function Wr-G{Write-Host ($args[0]) -F Green} # Writes supplied argument text in Green Function Wr-R{Write-Host ($args[0]) -F Red} # Writes supplied argument text in Red Function Wr-W{Write-Host ($args[0]) -F White} # Writes supplied argument text in White Function Wr-Y{Write-Host ($args[0]) -F Yellow} # Writes supplied argument text in Yellow Function Wn-C{Write-Host ($args[0]) -F Cyan -NoNewline} # Writes supplied argument text in Cyan (no new line after) Function Wn-G{Write-Host ($args[0]) -F Green -NoNewline} # Writes supplied argument text in Green (no new line after) Function Wn-R{Write-Host ($args[0]) -F Red -NoNewline} # Writes supplied argument text in Red (no new line after) Function Wn-W{Write-Host ($args[0]) -F White -NoNewline} # Writes supplied argument text in White (no new line after) Function Wn-Y{Write-Host ($args[0]) -F Yellow -NoNewline} # Writes supplied argument text in Yellow (no new line after) Function Rd-W{ # Read from host in White (because default isn't) If($args){Write-Host ($args[0]) -F White -NoNewline} # If supplied $args then write to the screen $args[0] first with NoNewLine return (Read-Host "?")} # Then prompt! Function Prompt-Keys{ # ------------------------------------------------------- # This expects key presses so the args should all be only one character long! Param([switch]$anykey,[switch]$echo) # Allows any key to be pressed / Allows the key to be echoed to screen If(!$anykey -and !$args[0]){return $false} # No args when not using the -anykey is not a valid option If($args[0]){ # Might have no $args[0] if using the -anykey option If($args[0].count -ne 1){$answers = $args[0]} # If the 1st argument - $args[0] - is an array, use this for the list of possible answers else{$answers = $args[0..(($args.count)-1)]} # Otherwise, take all the other arguments for the list of possible answers } # END of If ($args[0] while($true){ # Infinite loop! Escape via valid keypress or anykey if -anykey set! If ($echo){$keyPress = $host.UI.RawUI.ReadKey("IncludeKeyDown")} # The Key Press (ECHO allowed) else {$keyPress = $host.UI.RawUI.ReadKey("NoEcho,IncludeKeyDown")} # The Key Press (no ECHO) If($anyKey -and !$args[0]){return $true} # If $anyKey and no $args[0] we an return now $keyPress = $keyPress.character.ToString().ToUpper() # Compare in upper case (and return in upper case) foreach($answer in $answers){ # Loop through the answers if($keyPress -eq $answer.ToUpper()){return $keyPress} # Check if the answer to the prompt equals a valid answer, and if so then return } # END of foreach $answers If($anyKey){return $true} # If -anykey don't loop } # END of while $true } # --------------------------------------------------------------------------- # END of Prompt-Keys Function Set-Window{ # ---------------------------------------------------------- # Set-Window Param([string]$textcolor,[string]$background,[string]$title,[int]$percentMax) # -textcolor COLOR -background COLOR -title TITLE -percentMax %MAX_of_SCREEN_SIZE $window = (get-host).UI.RawUI # Gets the current Window properties If($textcolor) {$window.ForegroundColor = $textcolor} # If $textcolor parameter, sets the textcolor If($background -and ($window.BackgroundColor -ne $background)){ # If $background parameters and it's not equal to what it is set to already $window.BackgroundColor = $background;cls} # ... set the background and do a CLS If($title) {$window.WindowTitle = $title} # Set's the Window Title! $buffer = $window.BufferSize # Gets buffersize $buffer.Height = 9999 # ... set maximum buffer hit $window.BufferSize = $buffer # ... apply If($perCentMax){ # If $perCentMax parameter $maxX = [int](($window.MaxPhysicalWindowSize.Width)*$percentMax/100) # ... find our new X size $maxY = [int](($window.MaxPhysicalWindowSize.Height)*$percentMax/100) # ... find our new Y size $buffer.Width = $maxX # ... buffer = maxX $window.BufferSize = $buffer # ... apply $size = $window.WindowSize # ... get WindowSize $size.Width = $maxX # ... set maxX $size.Height = $maxY # ... set maxY $window.WindowSize = $size # ... apply } # END of $perCentMax } # ----------------------------------------------------------------------------- # END of Set-Window ################## # CORE FUNCTIONS # ################## Function Check-OSVersion{ # ----------------------------- # Checks the OS Version of the machine the script is running on Param([int]$major,[int]$minor) # INPUT = -major MAJORVERSION -minor MINORVERSION (e.g 2008R2 is 6 1) $currentOS = [System.Environment]::OSVersion.Version # Get the current OSVersion if ($currentOS.major -lt $major){return $null} # Current major version less than required major version - return FALSE elseif ($currentOS.major -gt $major){return $true} # Current major version greater than required major version - return TRUE elseif ($currentOS.minor -lt $minor){return $null} # Current minor version less than required minor version - return FALSE else {return $true}} # Current minor version greater than or equal to the minor - return TRUE Function Got-DFSUtil{ # ------------ # Tests if have access to DFSUtil Wr-E; $testDfsUtil = dfsutil.exe # This will output a big red error to screen if it fails and leave $testDfsUtil as $null return $testDfsUtil} # Return $testDfsUtil (either it's $null or has something in) Function Create-Folder { # ------------------------------------------------------- # INPUT = The folder or path to a folder for a new folder If(!$args[0]){ return $null } # If no/null argument supplied, return NULL If(Test-Path $args[0] -ErrorAction SilentlyContinue){ return ($args[0]) } # If it already exists, it returns back the name of the folder Else {[Void](New-item $args[0] -type directory -ErrorAction SilentlyContinue)} # Otherwise try and create it If(Test-Path $args[0] -ErrorAction SilentlyContinue){ return ($args[0]) } # If folder now exists, return back the name of the folder Else { return $null } # Otherwise return NULL } # ------------------------------------------------------------------------------ # END Create-Folder Function Prompt-ForDomainServersFile{ # Takes no input Wr-W "This program allows loading of a file with:" # Display to screen Wr-W "Line 1 = A domain name for Domain-based Namespaces" # Display to screen Wr-W "Line 2 = A comma separated list of servers for Standalone Namespaces" # Display to screen Wr-W "The file contents are not checked for validity.";Wr-E # Display to screen $readIn = Rd-W "Enter filepath";Wr-E # Read input return $readIn # Return what was read } # END of Prompt-ForDomainServersFile Function Prompt-ForDomain{ # Function takes no input $readIn = Rd-W "Enter domain name";Wr-E # Read in the domain name $getDFSUtil = Get-DFSUtil -Domain $readIn # Run Get-DFSUtil -Domain on the domain If(!$getDFSUtil){ # If was unsuccessful Wr-R "Unsuccessful querying domain $readIn for namespaces.";Wr-E # ... says it was unsuccessful return $false # return FALSE } # Wr-W ">>>>>>> List of Namespaces in $readIn";Wr-E # Display the list of Namespaces $getDFSUtil | foreach {Wr-W $_};Wr-E # Cycles through the Get-DFSUtil output return $readIn # return the domain name given in the prompt } # END of Prompt-ForDomain Function Prompt-ForServer{ # Function takes no input $readIn = Rd-W "Enter server name (or servers separated by commas)";Wr-E # Read in the server name(s) $split = $readIn.Split(",") # We allow comma separated servers, so split by this foreach ($server in $split) { # Cycle through the comma seperated list (or just a list of one) $getDFSUtil = Get-DFSUtil -Server $server # Run Get-DFSUtil -Server on the server If(!$getDFSUtil){ # If was unsuccessful Wr-R "Unsuccessful querying server $server for namespaces.";Wr-E # ... say it was unsuccessful return $false # return FALSE } # Wr-W ">>>>>>> List of Namespaces on $server";Wr-E # Display the list of Namespaces $getDFSUtil | foreach {Wr-W $_};Wr-E # Cycles through the Get-DFSUtil output } # END of cycling through servers return $readIn # return the server name(s) given in the prompt } # END of Prompt-ForServer Function Display-Namespaces{ # -------------------------- # Takes domain and/or server(s) as input Param($domain,$server) # Define the parameters $listNamespaces = @() # Define an array for the list of namespaces If($domain){ # If supplied a domain name Wr-W ">>>>>>> List of Namespaces in $domain";Wr-E # A heading $list = Get-DFSUtil -Domain $domain # Get the list of name spaces in the domain foreach($item in $list){ # FOR $list $namespace = "\\" + $domain + "\" + $item # Format Namespaces for domain $listNamespaces += $namespace # Add to $listNamespaces Wr-W $namespace # Display the namespaces } # END $list Wr-E # } # END of if $domain If($server){ # If supplied server(s) $split = $server.Split(",") # We allow comma separated servers, so split by this $split | foreach { # For each item (or just one) Wr-W ">>>>>>> List of Namespaces on $_";Wr-E # A heading $list = Get-DFSUtil -Server $_ # Get the list of name spaces in the standalone namespace foreach($item in $list){ # FOR $list $namespace = "\" + $item # Standalone namespaces just need a "\" on the front of "\COMPUTER" $listNamespaces += $namespace # Add to $listNamespaces Wr-W $namespace # Display the namespaces } # END $list Wr-E # } # END of $split for loop } # END of if $server , $listNamespaces # Return the list of Namespaces } # ----------------------------------------------------- # END of Display-Namespaces Function Get-DFSUtil { # Expected parameters: -Domain OR -Server Param([string]$Domain,[string]$Server) # Define parameters -Domain and -Server If($Domain){$dfsutilOut = dfsutil domain $Domain} # Run> dfsutil domain DOMAINNAME If($Server){$dfsutilOut = dfsutil server $Server} # Run> dfsutil server SERVERNAME If(!$dfsutilOut){return $false} # If no results, return FALSE If($dfsutilOut[0].contains("Could not complete the command")){ # dfsutil failed return $false # return FALSE } # END of if "Could not complete" $dfsNameSpaces = @() # Initialize the array $dfsNameSpaces Foreach ($line in $dfsutilOut) { # Cycle through the lines in the supplied (as 1st argument) array $line = $line.Trim() # Trim spaces from ends of line! $tmp = $line.ToLower() # $tmp (TeMPorary) is $line in lowercase (makes matching easier) If(($tmp -eq "") -or # not interested in blank lines ($tmp.StartsWith("roots on")) -or # not interested in this line ($tmp.StartsWith("done with")) -or # not interested in this line ($tmp.StartsWith("done processing"))){} # not interested in this line {do nothing...} else {$dfsNameSpaces += $line} # Construct $dfsNameSpaces } # END of Foreach in $args[0] , $dfsNameSpaces # Return $dfsNameSpaces } # END of Function Get-DFSUtil Function Prompt-ForNamespace { # ----------------------------------------- # Input is the list of namespaces from MAIN ($gotNameSpaces) Param($namespaces) # Define parameter $namespaces Wr-W ">>>>>>> List of Namespaces";Wr-E # A heading $namespaces | foreach {Wr-W $_};Wr-E # Write to screen all the namespaces $choice = Rd-W "Enter namespace";Wr-E # Prompt for the namespace If(!$choice){return "ALL"} # If user presses enter, return ALL ## Note: We cannot use -match for the matching because regex is confused by \ ## foreach ($namespace in $namespaces) { # START: Cycle through $namespaces If ( $namespace.ToUpper() -eq $choice.ToUpper() ) {return $choice} # If a match of the $choice in the $namespaces, return $choice ... } # END : Cycle through $namespaces Wr-R "Unable to match $choice from the list of namespaces!" # ... no match and say so Wr-E; return "ALL" # ... and return "ALL" } # ---------------------------------------------------------------------- # END Prompt-ForNamespace Function Backup-Namespaces { # --------------------------- # Backs up namespaces and returns an array with the filename(s) in Param($domain,$server,$namespace,$path) # Parameters -domain and/or -server, with -path Wn-W "Namespaces being backed up to "; Wr-C $path;Wr-E # Display $filenames = @() # Initialize $filenames array $date = Get-Date -uformat "%Y%m%d%H%M" # Get the date If($namespace -ne "ALL"){ # ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ # If have the $namespace parameter (but not for ALL) $split = $namespace.Split("\") # We have \\SERVER or DOMAIN\NAMESPACE - [0] \ [1] \ [2] \ [3] $filename = $path + "\" + $split[2] + "." + $split[3] + "." + $date + ".dfsnbackup" # Create filename [Void](Get-DFSUtilRootExport $namespace $filename) # Run Get-DFSUtilRootExport Wn-G "$namespace"; Wn-W " backed up to "; Wr-C "$filename"; Wr-E # write to screen return $filename # Return just one filename (since chosen to do 1 specific namespace) } # ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ # END of $namespace (NOTE: $namespace is overwritten later in this FN) If($domain){ # ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ # If DOMAIN $list = Get-DFSUtil -Domain $domain # Get the list of namespaces foreach($item in $list){ # cycle the list $filename = $path + "\" + $domain + "." + $item + "." + $date + ".dfsnbackup" # create filename $namespace = "\\" + $domain + "\" + $item # format namespace for dfsutil [Void](Get-DFSUtilRootExport $namespace $filename) # Run Get-DFSUtilRootExport $filenames += $filename # accumulate filenames Wn-G "$namespace"; Wn-W " backed up to "; Wr-C "$filename" # write to screen } # END of $list } # ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ # END of if DOMAIN If($server){ # ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ # If SERVER(s) $elements = $server.Split(",") # We allow comma separated servers, so split by this foreach($element in $elements){ # For each item (or just one) $list = Get-DFSUtil -Server $element # Get the list of namespaces foreach($item in $list){ # cycle the list $split = $item.Split("\") # Server items are \SERVER\NAMESPACE so we split them ([0] \ [1] SERVER \ [2] NAMESPACE) $filename = $path + "\" + $element + "." + $split[2] + "." + $date + ".dfsnbackup" # create filename $item = "\" + $item # format namespace for dfsutil [Void](Get-DFSUtilRootExport $item $filename) # Run Get-DFSUtilRootExport $filenames += $filename # accumulate filenames Wn-G "$item"; Wn-W " backed up to "; Wr-C "$filename" # write to screen } # END of $list } # END of $split for loop };Wr-E # ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ # END of SERVER , $filenames # Return $filenames } # ------------ # END of Backup-Namespaces Function Get-DFSUtilRootExport { # Expected parameters: -Namespace AND -Backup Param([string]$Namespace,[string]$Backup) # Define parameters -Namespace and -Backup $dfsutilout = dfsutil root export $Namespace $Backup # Get the DFS Namespace information and write to $Backup $tmp = $dfsutilout[1].ToString().ToLower() # $tmp (TeMPorary) is $dfsutilout in lowercase (makes matching easier) If($tmp.Contains("done processing this")){return $true} # Means successfully done a dfsutil root export $false # ... otherwise it failed! } # END of Function Get0DFSUtilRootExport Function Display-TableOfLinks{ # ---------------------------------------------------------------------- # START of Display-TableOfLinks Param($backupFiles) # Define param -backupfiles If(!$global:tableOfLinks){ # (v5.1) If $global:tableOfLinks is NULL [Void](Build-ArrayOfLinks $backupFiles) # ... build array of links $global:ToLcount = $global:tableOfLinks.count} # ... and count rows in the array (global) $r = 0;$x1 = 45;$x2 = 45;$x3 = 9;$x4 = 15 # Initialize row accumulator r=0 and column widths for the table Columnize "Namespace Link" $x1 White "Target" $x2 White "State" $x3 White "PriorityClass" $x4 White # Column Headings Columnize "--------------" $x1 White "------" $x2 White "-----" $x3 White "-------------" $x4 White # ... underlined while ($r -lt $global:ToLcount){ # While the row count is less than the number of rows (of 4) we have in the array Columnize ($global:tableOfLinks[$r]) $x1 White ($global:tableOfLinks[$r+1]) $x2 White ($global:tableOfLinks[$r+2]) $x3 White ($global:tableOfLinks[$r+3]) $x4 White $r += 4 # Accumulate the array by 4 for the next row } # END of while $r -lt $rows Wr-E # Write to screen a carriage return } # --------------------------------------------------------------------------------------------------- # END of FN (AKA - Display-DFSUtilRootExportTable modified) Function Build-ArrayOfLinks{ # --------------------------------------------------------- # Cycles through all the backup files building the array of links Param($backupFiles) # Define param -backupfiles $fileCount = $backupFiles.Count # A count of backup files $onFileNum = 1 # Initialize "On File Number" = 0 foreach ($file in $backupFiles){ # Cycle through backup files Wn-W ("Reading backup file " + $onFileNum + "/" + $fileCount + " - ");Wn-C $file # (v5.1) Display progress [Void](Get-DFSUtilRootExportTable $file) # (v5.1) Get-DFSUtilRootExportTable updates $global:tableOfLinks! $onFileNum ++ # Accumulate number of file we're on (progress display) } # END of $backupFiles Wr-E # } # ------------------------------------------------------------------------------------ # END of Build-ArrayOfLinks Function Get-DFSUtilRootExportTable { # ---------------------------------- # Expected parameter: -Filename # INPUT = $Filename of a DFSUTIL ROOT EXPORT file! # # OUTPUT = NONE! (Updates $global:tableOfLinks) # # USED BY = Function Build-ArrayOfLinks # Param([string]$Filename) # Define parameter -Filename $tmp = Test-Path $Filename # Test for $filename If(!$tmp){Wr-R "Filename $Filename not found!";return $null} # Return NULL and display a warning if $filename not found $contents = Get-Content -Path $Filename # Get the contents of $Filename If(!$contents){Wr-R "Filename $Filename has no content!";return $null} # Return NULL and display a warning if no content $recording = $false # Variable turns on/off recording from the file If (!$global:tableOfLinks){$global:tableOfLinks = @()} # (v5.1) A check that $global:tableOfLinks is not null, and if it is, to initialize as an array $split = $Filename.split("\") # (v5.1) We record full back to backup file and $split = $split[($split.count)-1] # (v5.1) ... just want the end bit (the file name) $split = $split.Split(".") # (v5.1) Split backup file name on "." $namespacePrefix = "\\" + $split[0] + "\" + $split[1] +"\" # (v5.1) The (DEFAULT) filename is DOMAIN/COMPUTER[0].NAMESPACE[1] Foreach ($line in $contents){ # Go through all the lines in $contents Wn-C "." # (v5.1) Display progress $tmp = $line.ToLower() # $tmp (TeMPorary) is $line in lowercase (makes matching easier) If($tmp.Contains("")){$recording = $false} # STOP recording contents of the file with "" If($recording){ # This bit only activates if $recording for servernames $split = $line.Split([char]34) # Split $line on Quotations $state = $split[1] # State is [0] " [1] STATE $priorityClass = $split[3] # Priority Class is [0] " [1] STATE " [2] " [3] PriorityClass $split = $line.Split(">") # Split $line on > $split = $split[1] # Take [1] ( [0] > [1] ) $split = $split.Split("<") # Split the above on < $target = $split[0] # Target is [0] Target < [1] $global:tableOfLinks += $link # (v5.1) Contruct array: link $global:tableOfLinks += $target # (v5.1) Contruct array: target $global:tableOfLinks += $state # (v5.1) Contruct array: state $global:tableOfLinks += $priorityClass # (v5.1) Contruct array: priorityClass } # END of $recording If($tmp.Contains(">>>>>>>>";Wr-E # Display TITLE $modes = "Set Referral Priority Class (For Clustered ONTAP)","Set State Online/Offline (For Data ONTAP 7-Mode)" # Initialize available modes $safeModes = "Safe Mode ENABLED (Updates NOT possible)!","Safe Mode DISABLED (UPDATES will be ACTIONED)!" # Initialize description for safe modes $mode = 0;$safeMode = $true # Initialize mode for CDOT and safe mode TRUE $nsChoice = "ALL"; $loadFile = $true # Initialize selection of ALL namespaces; enable loading the Domain Servers File on first run $global:tableOfLinks = $global:ToLcount = $global:targets = $null # Global variables we set to NULL $global:first = $global:last = $global:enabled = $global:disabled = $null # Global variables we set to NULL $reset1 = $reset2 = $reset4 = $reset4 = $domainName = $servers = $gotNameSpaces = $domainOrServer = $backup = $null # Non-global ones we set to NULL $backupPath = Create-Folder $backupPath # This returns back the default $backupPath if it was created or already exists Wn-W "Checking for the default Domain and Servers file at "; Wr-C $domainServersFile; Wr-E # Display on first running the script while($true){ # START of 'MAIN MENU SYSTEM' ... a perpetual loop If($loadFile){ # If $loadFile then load the domainServersFile If(Test-Path $domainServersFile){ # Check if a $domainServersFile exists $content = Get-Content $domainServersFile # Get the file contents If($content[0]){$domainName = $content[0]} # Domain is on the first line (or blank) If($content[1]){$servers = $content[1]} # Servers (separated by commas) are on the second line (or blank) } else { # Otherwise, no file $domainServersFile = $null # Set the string $domainServersFile to NULL } # NOTE: There is (currently) no error checking in here for the validity of the file contents $loadFile = $null # Will not reload the file on subsequent starts of the main menu (unless a new file is selected for loading) } # END: If $loadFile If ($reset1){$reset1 = $gotNameSpaces = $null; $nsChoice = "ALL"; $reset2 = $true} If ($reset2){$reset2 = $backup = $null; $reset3 = $true} If ($reset3){$reset3 = $global:tableOfLinks = $global:targets = $null; $reset4 = $true} If ($reset4){$reset4 = $global:first = $global:last = $global:enabled = $global:disabled = $null; $safeMode = $true} ## MAIN MENU ## Wr-W "<<<<<<<<< MAIN MENU >>>>>>>>>";Wr-E # MAIN MENU $PROMPTKEYS = "X","Q","B","1","2","3" # Initialize the key selections array with always available options If($domainName -or $servers){$domainOrServer = $true # Set the $domainOrServer flag to TRUE if we have any } else { $domainOrServer = $null} # ... otherwise set it to NULL # ~~~~~ DISPLAY: Options B,1 - 3 ~~~~~ # If($backupPath) { Wn-W " Change backup folder. Current = ";Wr-C $backupPath} else { Wr-R " Select a backup folder!"} If($domainServersFile){ Wn-W " <1> Reload Domain and Server(s) from file. Last loaded = ";Wr-C $domainServersFile} else{ Wr-W " <1> Load Domain and Server(s) from file"} If($domainName){ Wn-W " <2> Change Domain. Currently selected = ";Wr-G $domainName} else{ Wr-W " <2> Enter Domain Name (for Domain-based namespaces)"} If($servers){ Wn-W " <3> Change Server(s). Currently selected = ";Wr-G $servers} else{ Wr-W " <3> Enter Server Name(s) (for Standalone namespaces)"} # ~~~~~ DISPLAY: Options 4 - 8 ~~~~~ # If($domainOrServer){ Wr-E;Wr-W " <4> Display Namespaces";$PROMPTKEYS += "4"} If($gotNameSpaces){ Wn-W " <5> Select an individual namespace/select ALL. Currently selected = ";Wr-C $nsChoice;$PROMPTKEYS += "5"} If($gotNameSpaces -and $backupPath){ Wr-W " <6> Backup Namespaces";$PROMPTKEYS += "6"} If($backup){ Wr-W " <7> Display Table of Links, Target, State and PriorityClass";$PROMPTKEYS += "7"} If($global:tableOfLinks){ Wr-W " <8> Display List of Servers with Targets in the Namespaces";$PROMPTKEYS += "8"} # ~~~~~ DISPLAY: Options T,F,L,E,D ~~~~~ # $common = "Set Server whose Targets are to be set as" If($global:targets){ Wr-E;Wn-W " (T)oggle Mode of Operation. Current = ";Wr-C $modes[$mode];$PROMPTKEYS += "T" If($mode -eq 0){ $PROMPTKEYS += "F","L" If($global:first){ Wn-W " $common Priority (F)irst. "; Wr-G ("Selected = " + $global:first)} else{ Wr-W " $common Priority (F)irst."} If($global:last){ Wn-W " $common Priority (L)ast . "; Wr-G ("Selected = " + $global:last)} else{ Wr-W " $common Priority (L)ast ."} } else { $PROMPTKEYS += "E","D" If($global:enabled){ Wn-W " $common (E)nabled . "; Wr-C ("Selected = " + $global:enabled)} else{ Wr-W " $common (E)nabled ."} If($global:disabled){Wn-W " $common (D)isabled. "; Wr-C ("Selected = " + $global:disabled)} else{ Wr-W " $common (D)isabled."}}} # ~~~~~ DISPLAY: Options C,S,U ~~~~~ # If($global:last -or $global:first -or $global:enabled -or $global:disabled){ $PROMPTKEYS += "S","C","U" Wr-E;Wr-C " Display DFSUTIL (C)ommands that will be run." If($safeMode){ Wn-G " Toggle (S)afe Mode On/Off. Current = "; Wr-G $safeModes[0] Wr-G " (U)PDATE DFS!" } else { Wn-Y " Toggle (S)afe Mode On/Off. Current = "; Wr-Y $safeModes[1] Wr-Y " (U)PDATE DFS!"}} # ~~~~~ DISPLAY: Exit and Press a Key ~~~~~ # Wr-E;Wr-W " E(X)it/(Q)uit!" Wr-E;Wn-G " <<<<< Press a Key: " ## Handle the Keys ## $key = Prompt-Keys $PROMPTKEYS;Wr-Y $key; Wr-E # <<<<<<< HANDLE: X,B,1,2,3 >>>>>>> # If(($key -eq "X") -or ($key -eq "Q")){EXIT} If($key -eq "B"){$backupPath = Rd-W "Enter backup folder path"; $backupPath = Create-Folder $backupPath; Wr-E; $reset2 = $true} If($key -eq "1"){$domainServersFile = Prompt-ForDomainServersFile; $loadFile = $true; $reset1 = $true} If($key -eq "2"){$domainName = Prompt-ForDomain; $reset1 = $true} If($key -eq "3"){$servers = Prompt-ForServer; $reset1 = $true} # <<<<<<< HANDLE: 4 - 8 >>>>>>> # If($key -eq "4"){$gotNameSpaces = Display-Namespaces $domainName $servers} # KEY: "4" get's a properly formatted table of Namespaces If($key -eq "5"){ # KEY: "5" selection $newChoice = Prompt-ForNamespace $gotNameSpaces # Prompt for new choice if NameSpace If($newChoice -ne $nsChoice){$reset2 = $true} # If $newChoice is different to the old, we need to reset $reset2 set of variables $nsChoice = $newChoice # Always set $nsChoice to $newChoice } # END: "5" selection If($key -eq "6"){ # KEY: "6" for backup! $backup = Backup-Namespaces -Domain $domainName -Server $servers -Namespace $nsChoice -Path $backupPath $reset3 = $true} # Running a backup always re-initializes the $global:tableOfLinks to a NULL array If($key -eq "7"){[Void](Display-TableOfLinks $backup)} # KEY: "7" generates and/or displays $global:tableOfLinks If($key -eq "8"){[Void](Display-TargetServers)} # KEY: "8" generates and/or displays $global:targets (hashtable of target servers & occurrences) # <<<<<<< HANDLE: T,F,L,E,D >>>>>>> # If($key -eq "T"){ # KEY: "T" (T)oggle If($mode -eq 0){$mode = 1} # Mode now "Set State" else {$mode = 0} # Mode now "Set PriorityClass" $reset4} # Toggling mode resets these variables If($key -eq "F"){$global:first = Prompt-ForTarget} # KEY: "F" If($key -eq "L"){$global:last = Prompt-ForTarget} # KEY: "L" If($key -eq "E"){$global:enabled = Prompt-ForTarget} # KEY: "E" If($key -eq "D"){$global:disabled = Prompt-ForTarget} # KEY: "D" # <<<<<<< HANDLE: S,C,U >>>>>>> # If($key -eq "S"){ # START: S selection for (S)afe If($safeMode){$safeMode = $null} # ... not SAFE mode else {$safeMode = $true}} # ... now SAFE mode If($key -eq "C"){ # --------------------- # START: C selection for (C)ommands [Void](Update-DFSUtil -ShowCommands)} # ... RUN but just show commands If($key -eq "U"){ # --------------------- # START: U selection for (U)pdate If($safeMode){ # ... If safe mode [Void](Update-DFSUtil -Safe) # RUN Update-DFSUtil in safe mode } else { # ... else ... [Void](Update-DFSUtil) # RUN Update-DFSUtil $reset2 = $true # ... after FULL run, run $reset2 (will need to backup before more changes!) } # END: NOT $safeMode } # ------------------------------------- # END: R selection } # END of 'MAIN MENU SYSTEM' ... loop back to start ######################### ## END of MAIN PROGRAM ## #########################