Attempted to divide by zero | Issue resolved

This topic contains 5 replies, has 3 voices, and was last updated by Profile photo of  Anonymous 1 year, 11 months ago.

  • Author
    Posts
  • #24395
    Profile photo of
    Anonymous

    Hi Guys,
    I am writing the below code is to reboot all the DAG nodes in a given DAG. I am in middle of this task and encountering an issue with PS 2.0 vs 4.0.
    Initially I started writing my code in one of the exchange server which is equipped with PS 2.0. Because of screen size limitations of this VM and to fix the attached bugs, I configured PSSession on my host machine which is running on Win 8.1 (PS 4.0).

    Surprisingly when I just ran the sane code against on PS 4.0 it started working with out any issues. to confirm I went back and ran the same code again on 2.0 still issue persists.

    Please help me to fix this issue. You can just run the script with an invalid host name which will result the issue (on 2.0). Also comment on my coding standards which I want improve.

    Function MaximizeWindow # Function to check and adjust current PS console window sizes.
    {
    	Write-Verbose "Window Maximize : Started."
    	Write-Progress -Activity "Window Adjustment" -Status 'Initializing' -ID 0 -PercentComplete 50 -CurrentOperation "Setting screen buffer size and Window size to equal to each other and also setting screen buffer size width value to 9999 which enables to have  lengthy vertical scroll bar."
    	Write-Verbose "Window Maximize : Setting screen buffer size and Window size to equal to each other and also setting screen buffer size width value to 9999 which enables to have  lengthy vertical scroll bar."
    	$ErrorActionPreference = "SilentlyContinue"
    	$temp_PSCal1=$Host.UI.RawUI.MaxPhysicalWindowSize
    	$temp_PSCal1.Width-=3
    	$temp_PSCal1.Height=9999
    	$Host.UI.RawUI.BufferSize=$temp_PSCal1
    	$temp_PSCal2=$Host.UI.RawUI.WindowSize
    	$temp_PSCal2.Width=$temp_PSCal1.Width-=3
    	$Host.UI.RawUI.WindowSize=$temp_PSCal2
    	$memberDefinition = @'
    	[DllImport("user32.dll")] public static extern bool ShowWindow(IntPtr hWnd, int nCmdShow);
    	[DllImport("user32.dll", SetLastError = true)] public static extern bool SetForegroundWindow(IntPtr hWnd);
    '@
    	Add-Type -MemberDefinition $memberDefinition -Name Api -Namespace User32
    	[int]$hwnd = Get-Process -Id $PID | Select-Object -ExpandProperty MainWindowHandle
    	If ($hwnd)
    	{
    		$onTop = New-Object -TypeName System.IntPtr -ArgumentList (0)
    		$null=[User32.Api]::SetForegroundWindow($hwnd)
    		$null=[User32.Api]::ShowWindow($hwnd, 3)
    	}
    	$ErrorActionPreference = "Continue"
    	Write-Progress -Activity "Window Adjustment" -Status 'Completed' -ID 0 -PercentComplete 100 -CurrentOperation "Screen adjustments completed."
    	Write-Verbose ("Window Maximize : Completed.")
    	Return [Bool]$True
    }
    Function LoadExchangeSnapin # Function to check and load Exchange Snap-in.
    {
    	##################################################################### Notes about logic starts here ########################################################################################
    	# We cannot add exchange snap-in to a local PowerShell profile and which may be connect to a host of exchange host in a PSSession manner. So the below logic checks the same.
    	##################################################################### Notes about logic ends here   ########################################################################################
    	Write-Verbose "Exchange Snap-in: Started."
    	Write-Verbose "Exchange Snap-in: Checking whether Exchange Snap-in is loaded or not."
    	Write-Progress -Activity "Exchange Snap-in" -Status 'Initializing' -ID 0 -PercentComplete 50 -CurrentOperation "Verifying the Exchange Snap-in load status."
    	If (!(Get-PSSnapin Microsoft.Exchange.Management.PowerShell.E2010 -ErrorAction:SilentlyContinue)) # Checking Exchange Snap-in load status
    	{
    		Write-Verbose "Exchange Snap-in: Exchange Snap-in is not loaded, now proceeding to load it."
    		Write-Progress -Activity "Exchange Snap-in" -Status 'Initializing' -ID 0 -PercentComplete 80 -CurrentOperation "Loading Exchange Snap-in."
    		Try
    		{
    			Add-PSSnapin Microsoft.Exchange.Management.PowerShell.E2010 -ErrorAction:Stop # Trying to load Exchange Snap-in
    			Write-Verbose "Exchange Snap-in: Exchange Snap-in is loaded now successfully."
    			Write-Progress -Activity "Exchange Snap-in" -Status 'Initializing' -ID 0 -PercentComplete 100 -CurrentOperation "Loaded the Exchange Snap-in successfully."
    		}
    		Catch # Unable to load the snap-in
    		{
    			$BlackHole1 = Get-PSSession #Checking whether the host is having any active PSSessions with any of the Exchange host.
    			Foreach($B in $BlackHole1)
    			{
    				If($B.ConfigurationName -like '*Exchange*') # This will get passed when a PSSession found with a Exchange host.
    				{
    					Write-Verbose "Exchange Snap-in: Found that the command ran from local machine ($ENV:ComputerName) and hence cannot load Exchange Snap-in. Now proceeding to check if this host $ENV:Computername is having any active PSSessions with any Exchange server."
    					$BlackHole2 = Get-MailboxDatabaseCopyStatus -WarningAction SilentlyContinue -ErrorAction Stop # It is not enough just having PSSessions. Here I am checking whether Exchange commands are working or not?
    					If($BlackHole2 -ne $Null) # This will get passed if Exchange commands works.
    					{
    						Write-Verbose $("Exchange Snap-in: Found the machine $ENV:ComputerName had already established one PSSession with the host:  "+$($B.ComputerName).ToUpper())
    						[bool]$FoundAtLeastOnePSSession = $True # As we may have multiple PSSessions other than Exchange hence I am making True when Exchange PSSession found just to skip for rest of all in else spot of the above IF condition
    						Write-Verbose $("Exchange Snap-in: Completed")
    					}
    					Else #Found an active PSSession with a Exchange host but Exchange commands are not working.
    					{
    						Write-Warning "Cannot find any active PSSessions or unable to load Exchange Snap-ins. Please very Exchange commands or working or not."
    						Write-Verbose $("Exchange Snap-in: Completed")
    					}
    					Write-Progress -Activity "Exchange Snap-in" -Status 'Completed' -ID 0 -PercentComplete 100 -CurrentOperation "Loaded the Exchange Snap-in successfully."
    					Return [Bool]$True
    				}
    				Else
    				{
    					If($FoundAtLeastOnePSSession -eq $False) # FoundAtLeastOnePSSession will be False when at least one PSSessions of exchagne not found.
    					{
    						Write-Warning "Cannot find any active PSSessions or unable to load Exchange Snap-ins. Please very Exchange commands or working or not."
    						Write-Progress -Activity "Exchange Snap-in" -Status 'Completed' -ID 0 -PercentComplete 100 -CurrentOperation "Cannot load the snapin"
    						Write-Verbose $("Exchange Snap-in: Completed")
    						Return [Bool]$False
    					}
    				}
    			}
    		}
    	}
    	Else
    	{
    		Write-Progress -Activity "Exchange Snap-in" -Status 'Completed' -ID 0 -PercentComplete 100 -CurrentOperation "Loaded the Exchange Snap-in successfully."
    		Write-Verbose $("Exchange Snap-in: Completed")
    		Return [Bool]$True
    	}
    }
    Function WhoRanIt # Function to check who ran the script.
    {
    	Write-Verbose "Who Ran The Script: Started."
    	Write-Progress -Activity "Identifying" -Status 'Initializing' -ID 0 -PercentComplete 50 -CurrentOperation "Checking that who ran the script"
    	$Global:WhoRanIt = $Null #Global Variable to catch who ran the script
    	$WhoRanIt=$($ENV:UserName).ToUpper()
    	Write-Verbose $("Who Ran The Script: '"+$WhoRanIt+"'"+" Ran the script")
    	Write-Progress -Activity "Identifying" -Status 'Initializing' -ID 0 -PercentComplete 100 -CurrentOperation $($WhoRanIt+" Ran the script.")
    	Write-Verbose "Who Ran The Script: Completed."
    	Return [String]$WhoRanIt
    }
    Function DAG_Validation # Function to check and validate the -DAG inputs and its nodes.
    {
    	[CMDLetBinding()]
    	Param(
    		$DAG_User_Input 
    	)
    	BEGIN
    	{
    		[int]$Count = 0
    		#$DAG_User_Input = $DAG_User_Input | Select-Object -Uniq # There is a change that the user may duplicate the DAG name inputs. Hence finally I am filtering only for unique values.
    	}
    	PROCESS
    	{
    		Write-Verbose "DAG Validation  : Started."
    		Foreach($D in $DAG_User_Input)
    		{
    			Write-Verbose $("DAG Validation  : Validating the DAG: '"+$D.ToUpper()+"'")
    			$Count++
    			Try
    			{
    				Write-Progress -Activity "-DAG validation" -Status 'InProgress' -ID 0 -PercentComplete (($Count/($DAG_User_Input.count))*100) -CurrentOperation "Validating the DAG name : $D"
    				$Servers = Get-DatabaseAvailabilityGroup $D -ErrorAction 'Stop' # Fetching the list of DAG nodes to the variable
    				[Array]$DAG_Servers += $Servers.Servers # Adding each node from each DAG to the variable
    				Write-Verbose $("DAG Validation  : Validation completed : '"+$D.ToUpper()+"' is a valid DAG input.")
    			}
    			Catch
    			{
    				# When the above try fails then the below statements conveys that the given DAG name is invalid.
    				Write-Error $("Cannot find any DatabaseAvailabilityGroup by the name '"+$D.ToUpper()+"'. Please enter a valid DatabaseAvailabilityGroup name.")
    				Write-Verbose $("DAG Validation: Validation completed. ': "+$D.ToUpper()+"' is an invalid DAG input.")
    			}
    		}
    		Write-Progress -Activity "-DAG validation" -Status 'Completed' -ID 0 -PercentComplete 100 -CurrentOperation "Validation completed" -Completed
    		Write-Verbose $("DAG Validation  : Completed.")
    		Return [Array]$DAG_Servers # Returning the final result from this function definition to the function call location.
    	}
    	END{}
    }
    Function Node_ExcludeNode_Validation # Function to check and validate the inputs given for -ExcludeNode or -Node parameters.
    {
    	[CMDLetBinding()]
    	Param(
    		$Exception_User_Input 
    	)
    	BEGIN
    	{
    		[int]$Count = 0
    		$Exception_User_Input = $Exception_User_Input | Select-Object -Uniq
    	}
    	PROCESS
    	{
    		[int]$Count = 0 # Variable for counting purpose.
    		Foreach($E in $Exception_User_Input)
    		{
    			If($Node) # Here we need to produce the progress bar based on the parameter which is using this function, i.e., either -Node or -ExcludeNode. This IF sopt is for -Node parameter
    			{
    				Write-Verbose "Node Validation: Started"
    				#Progress bar when In-Progress
    				Write-Progress -Activity "Node Validation Tests Are Started" -Status 'InProgress' -PercentComplete (($Count/($Exception_User_Input.Count))*100) -CurrentOperation $("Validating the -Node name : "+$E.ToUpper())
    			}
    			Else # This ELSE spot is for -Exclude parameter
    			{
    				#Progress bar when In-Progress
    				Write-Verbose "ExcludeNode Validation: Started"
    				Write-Progress -Activity "ExcludeNode Validation Tests Are Started" -Status 'InProgress' -PercentComplete (($Count/($Exception_User_Input.Count))*100) -CurrentOperation $("Validating the -ExcludeNode name : "+$E.ToUpper())
    			}
    			Write-Progress -Activity "PING Test" -Status 'InProgress' -PercentComplete 50 -CurrentOperation $("Performing PING Test For The Host : "+$E.ToUpper())
    			If(!$Node)
    			{
    				Write-Verbose $("ExcludeNode Validation: Performing PING test for '"+$E.ToUpper()+"'")
    			}
    			Else
    			{
    				Write-Verbose $("ExcludeNode Validation: Performing PING test for '"+$E.ToUpper()+"'")
    			}
    			$BlackHole = Test-Connection $E -Count 1 -ErrorAction 'SilentlyContinue' # Performing the ping test and taking only the first count among 4 ping packet test results.
    			If($BlackHole -ne $Null) # This comparison will be passed when the first ping packet test results are return by the Test-Connection command.
    			{
    				Write-Progress -Activity "PING Test" -Status 'Completed' -PercentComplete 100 -CurrentOperation $("PING Test For The Host : "+$E.ToUpper())
    				If(!$Node)
    				{
    					Write-Verbose $("ExcludeNode Validation: '"+$E.ToUpper()+"'PING test passed")
    				}
    				Else
    				{
    					Write-Verbose $("Node Validation: '"+$E.ToUpper()+"'PING test passed")
    				}
    				$E = $E.ToString() # Converting the host name datatype to string
    				$E = $E.ToUpper() # Converting the host name to upper case.
    				Write-Progress -Activity "Exchange Host or not?" -Status 'InProgress' -PercentComplete 50 -CurrentOperation $("Checking whether the host : "+$E.ToUpper()+" is an Exchange host or not?")
    				If(!$Node)
    				{
    					Write-Verbose $("ExcludeNode Validation: Checking the host'"+$E.ToUpper()+"' is an Exchange host or not?")
    				}
    				Else
    				{
    					Write-Verbose $("Node Validation: Checking the host'"+$E.ToUpper()+"' is an Exchange host or not?")
    				}
    				$Version = Get-ExchangeServer $E.ToUpper() -ErrorAction 'SilentlyContinue' # Checking whether the current host is an Exchange host or not
    				# For the below IF condition: Comparing with the standard FQEID which will be written when the host is not an Exchange one by the Get-Exchange command.
    				If(!($(($Error[0]).FullyQualifiedErrorId) -like "*,Microsoft.Exchange.Management.SystemConfigurationTasks.GetExchangeServer*"))
    				{
    					Write-Progress -Activity "Exchange Host or not?" -Status 'Completed' -PercentComplete 100 -CurrentOperation $(""+$E.ToUpper()+" is an Exchange host")
    					Write-Progress -Activity "Exchange 2010 Host or not?" -Status 'InProgress' -PercentComplete 50 -CurrentOperation $("Checking whether the host : "+$E.ToUpper()+" is an Exchange 2010 host or not?")
    					If(!$Node)
    					{
    						Write-Verbose $("ExcludeNode Validation: '"+$E.ToUpper()+"' Is an Exchange host.")
    						Write-Verbose $("ExcludeNode Validation: Checking '"+$E.ToUpper()+"' is Exchange 2010 or 14.X above or not?")
    					}
    					Else
    					{
    						Write-Verbose $("Node Validation: '"+$E.ToUpper()+"' Is an Exchange host.")
    						Write-Verbose $("Node Validation: Checking '"+$E.ToUpper()+"' is Exchange 2010 or 14.X above or not?")
    					}
    
    					If($Version.IsE14OrLater -eq $True) # Exchange version should be 14 or above which confirms that the host is Exchange 2010
    					{
    						Write-Progress -Activity "Exchange 2010 Host or not?" -Status 'Completed' -PercentComplete 100 -CurrentOperation $(""+$E.ToUpper()+" is an Exchange 2010 host")
    						If(!$Node)
    						{
    							Write-Verbose $("ExcludeNode Validation: '"+$E.ToUpper()+"' is an Exchange 2010 or 14.X above version")
    						}
    						Else
    						{
    							Write-Verbose $("Node Validation: '"+$E.ToUpper()+"' is an Exchange 2010 or 14.X above version")
    						}
    						[array]$EX_or_DAG_Servers += $E.ToUpper() # Accumulating the validated hosts names in $E to the another array type of variable to have it as a collection.
    					}
    					Else
    					{
    						Write-Progress -Activity "Exchange 2010 Host or not?" -Status 'Completed' -PercentComplete 100 -CurrentOperation $(""+$E.ToUpper()+" is not an Exchange 2010 host") -completed
    						If(!$Node)
    						{      
    							Write-Verbose $("ExcludeNode Validation: '"+$E.ToUpper()+"' is not an Exchange 2010 or 14.X above version")
    						}
    						Else
    						{
    							Write-Verbose $("Node Validation: '"+$E.ToUpper()+"' is not an Exchange 2010 or 14.X above version")
    						}
    						Write-Error $("The node '"+$E.ToUpper()+"' is not Exchange 2010 or its an earlier version than 14.X. Please enter only Exchange 2010 host only.") # This will happen when version < =14.X.
    					}
    				}
    				Else
    				{
    					# "*,Microsoft.Exchange.Management.SystemConfigurationTasks.GetExchangeServer" is the standard FQEID when the host is not an Exchange one. Hence this spot will get executed when its corresponding IF fails.
    					# Here we need to produce the Errors based on the parameter which is using this function, i.e., either -Node or -ExcludeNode
    					Write-Progress -Activity "Exchange Host or not?" -Status "Completed" -PercentComplete 100 -CurrentOperation $(""+$E.ToUpper()+" is not an Exchange host") -ParentId 0 -Completed
    					If($Node) # Its for -Node parameter
    					{
    						Write-Verbose $("Node Validation: The input given for the parameter "+""Node = "+$E.ToUpper()+"""+" is not an Exchange Server. Please check the input.")
    					}
    					Else # Its for -ExcludeNode parameter
    					{
    						Write-Verbose $("ExcludeNode Validation: The input given for the parameter "+""ExcludeNode = "+$E.ToUpper()+"""+" is not an Exchange Server. Please check the input.")
    					}
    				}
    			}
    			Else # This Else spot will get executed when host is unable to ping
    			{
    				Write-Progress -Activity "PING Test" -Status "Completed" -PercentComplete 100 -CurrentOperation $("PING Test For The Host : "+$E.ToUpper()+" Failed") -Completed
    			If(!$Node)
    			{
    				Write-Verbose $("ExcludeNode Validation: ""+$E.ToUpper()+"" PING test failed.")
    			}
    			Else
    			{
    				Write-Verbose $("ExcludeNode Validation: ""+$E.ToUpper()+"" PING test failed.")
    			}
    				Write-Error $("""+$E.ToUpper()+"" Is not pingable. Please check the host.")
    			}
    
    		}
    		If($Node) # Here we need to produce the progress bar based on the parameter which is using this function, i.e., either -Node or -ExcludeNode. This IF sopt is for -Node parameter
    		{
    			#Turning the progress bar to Completed with all inputs are validated.
    			Write-Progress -Activity "Node validation" -Status "Completed" -PercentComplete 100 -CurrentOperation "Validation completed" -Completed
    			Write-Verbose "Node Validation: Completed"
    		}
    		Else # This ELSE spot is for -Exclude parameter
    		{
    			#Turning the progress bar to Completed with all inputs are validated.
    			Write-Progress -Activity "ExcludeNode validation" -Status "Completed" -PercentComplete 100 -CurrentOperation "Validation completed" -Completed
    			Write-Verbose "ExcludeNode Validation: Completed"
    		}
    		$EX_or_DAG_Servers = $EX_or_DAG_Servers | Select-Object -Uniq
    		Return [Array]$EX_or_DAG_Servers
    	}
    }
    Function DAG_and_ExcludeNode_Calculation($DAG_Rslt,$EXCLND_Rslt)
    {
    	[int]$i = 0
    	Write-Verbose $("DAG & ExcludeNode Inputs Validation: Started")
    	$Calculation_Result = New-Object System.Collections.ArrayList # Creating new .Net array type of object which allows .Add() or .Remove() methods. This is needed to exclude the nodes from DAG nodes list.
    	ForEach($t in $DAG_Rslt)
    	{
    		$Calculation_Result.Insert([int]$i,$t) # Firstly adding each node name to the variable.
    	}
    	$Common_Hosts = $DAG_Rslt | ?{$EXCLND_Rslt -Contains $_} # Filtering the common host names from both -ExcludeNode list and DAG nodes list.
    	Foreach($temp_EXCLND_Rslt in $EXCLND_Rslt)
    	{
    		$Count = 0 # Variable for count purpose
    		$NotFound = 0 # Variable for count purpose
    		Foreach($temp_DAG_Rslt in $DAG_Rslt)
    		{
    			Write-Verbose $("DAG & ExcludeNode Inputs Validation: "+$temp_DAG_Rslt+" = "+$temp_EXCLND_Rslt+" ?")
    			If($temp_DAG_Rslt -eq $temp_EXCLND_Rslt) # Checking each node in exclude node is matching with DAG nodes?
    			{
    				#Write-Progress -Activity "DAG & ExcludeNode Inputs Validation" -Status "InProgress" -PercentComplete 50 -CurrentOperation $($temp_DAG_Rslt+"="+$temp_EXCLND_Rslt)
    				Write-Verbose $("DAG & ExcludeNode Inputs Validation: "+$temp_DAG_Rslt+" = "+$temp_EXCLND_Rslt+" : PASS")
    				$Count++ # Matching found. Increasing the count value
    				$Calculation_Result.Remove($temp_EXCLND_Rslt) # As matching found, removing the matched host from the .net array variable DAG list.
    			}
    			Else
    			{
    				#Write-Progress -Activity "DAG & ExcludeNode Inputs Validation" -Status "InProgress" -PercentComplete 50 -CurrentOperation $($temp_DAG_Rslt+"!="+$temp_EXCLND_Rslt)
    				Write-Verbose $("DAG & ExcludeNode Inputs Validation: "+$temp_DAG_Rslt+" != "+$temp_EXCLND_Rslt+" FAIL")
    				$NotFound++ # Match not found. Which also means that the input given in -ExcludeNode is not a member of the provided -DAG
    			}
    			If([int]$NotFound -eq $DAG_Rslt.Count) # When the not found count variable is equal to total number of DAG members then its successfully unable to find the node in -ExcludeNode.
    			{
    				[Array]$NotFound_List+= $temp_EXCLND_Rslt # Catching the current unsuccessful findings of the host name in DAG member list. Its because to display the host names in Write-Error
    				$NotFound_List = $NotFound_List | Select-Object -Uniq # Selecting unique host names only
    				[Bool]$Issue = $True # If I write Write-Error it displays many number of times i.e., number of unsuccessful times with each matching test with DAG node. To avoid this I just defined a bool variable and will make use of this in the below IF.
    			}
    			Write-Progress -Activity "DAG & ExcludeNode Inputs Validation" -Status "Completed" -PercentComplete 100 -Completed
    		}
    	}
    	If($Issue) # As explained in the location where $Issue variable defined, writing the error to the ERROR stream
    	{
    		Write-Error $("We cannot find "+$NotFound_List+" as a DAG member of any you inputted to -DAG list. ExcludeNode list should be a member of the DAG")
    	}
    	Write-Verbose $("DAG & ExcludeNode Inputs Validation: Completed")
    	#$Calculation_Result
    	Return $Calculation_Result # Returning the result of this function definition to the function call location.
    }
    Function Node_Members_Validation($Nodes)
    {
    	ForEach($N in $Nodes)
    	{
    		$Node_Validation = Get-MailboxServer $N -ErrorAction "SilentlyContinue" 		
    		
    	}
    }
    Function Uptime($ComputerName) #Function to calculate update of the given host.
    {
    	Write-Progress -Activity "Uptime" -Status "InProgress" -PercentComplete 50 -CurrentOperation $("Calculating System Uptime for :"+$ComputerName)
    	sleep 1
    	Write-Verbose $("Calculating system uptime : "+$ComputerName)
    	Try
    	{
    		$Uptime = Get-WmiObject -Class Win32_PerfFormattedData_PerfOS_System -ComputerName $ComputerName -ea 1|Select-Object @{Name = "SystemUpTime"; Expression = {New-TimeSpan -Seconds $_.SystemUpTime}}
    	}
    	catch
    	{
    		Write-Verbose $("Host ""+$ComputerName.ToUpper()+"" has failed to get the uptime. Now proceeding to check whether the host is pingable or not?...")
    		$PingTest=Get-WMIObject -Query "select * from win32_pingstatus where Address="$H""
    		If($PingTest.StatusCode -eq 0)
    		{
    			write-verbose $("Host: "" +($ComputerName) +"" is pingable but unable to get the uptime of the host.")
    			Write-warning $("Host: "" +($ComputerName).ToUpper() +"" is pingable but unable to get the uptime of the host. Please do manual checks")
    		}
    		else
    		{
    			write-verbose $("Host: "" +($ComputerName) +"" is NOT pingable.")
    			Write-Host $("Host: "" +($ComputerName).ToUpper() +"" is NOT pingable. Please check the host") -foreg RED
    		}
    	}
    	Write-Progress -Activity "Uptime" -Status "Completed" -PercentComplete 100
    	Return $Uptime
    }
    Function Do-PreRebootCheck # Main Function
    {
    	[CMDLetBinding()]
    	param(
    		[parameter(Mandatory=$False,ValueFromPipeline=$True,Position=0)][String[]]$DAG,
    		[parameter(Mandatory=$False,ValueFromPipeline=$True,Position=1)][String[]]$ExcludeNode,
    		[parameter(Mandatory=$False,ValueFromPipeline=$True,Position=0)][String[]]$Node
    	)
    	BEGIN
    	{
    		$Null = MaximizeWindow
    		$Null = LoadExchangeSnapin
    	}
    	Process
    	{
    		$CustomErrorMessage = "`t You cannot have the below combination of the parameters.`n`t`t`t`t1. You cannot have both DAG & Node parameters at single instance.`n`t`t`t`t2. You cannot have the parameter ExcludeNode alone without DAG parameter"
    		Switch ($True)
    		{
    			{($DAG) -and (-not $Node) -and (-not $ExcludeNode)} # Works only when -DAG is given
    			{
    				$DAG_Result = DAG_Validation -DAG_User_Input $DAG
    				If($DAG_Result -ne $Null)
    				{
    					$Final_List_Of_Nodes_To_Be_Reboot = $DAG_Result
    					$Uptime = Uptime -ComputerName $Final_List_Of_Nodes_To_Be_Reboot
    					$Uptime
    				}
    			}
    			{($ExcludeNode) -and ($DAG) -and (-not $Node)} # Works when -DAG and -ExcludeNode are given
    			{
    			
    				$DAG_Result = DAG_Validation -DAG_User_Input $DAG
    				If($DAG_Result -ne $Null)
    				{
    					$ExcludeNode_Result = Node_ExcludeNode_Validation -Exception_User_Input $ExcludeNode
    					$Final_List_Of_Nodes_To_Be_Reboot = DAG_and_ExcludeNode_Calculation -DAG_Rslt $DAG_Result -EXCLND_Rslt $ExcludeNode_Result
    					If($Final_List_Of_Nodes_To_Be_Reboot -ne $Null)
    					{
    						$Uptime = Uptime -ComputerName $Final_List_Of_Nodes_To_Be_Reboot
    						$Uptime
    					}
    					Else
    					{
    						Write-Error "You cannot exclude all nodes from the DAG because it will turn  DAG input into an empty."
    					}
    				}
    				Else{}
    			}
    		
    			{($Node) -and (-not $DAG) -and (-not $ExcludeNode)} # Works only when -Node is given
    			{
    				$Node_Result = Node_ExcludeNode_Validation -Exception_User_Input $Node
    				$Final_List_Of_Nodes_To_Be_Reboot = Uptime -ComputerName $Node_Result
    				$Final_List_Of_Nodes_To_Be_Reboot
    			}
    			Default # Works only when condition fails.
    			{
    				Write-Warning $CustomErrorMessage
    			}
    		}
    	}
    }
    
  • #24401
    Profile photo of Dave Wyatt
    Dave Wyatt
    Moderator

    That's a lot of code to look at. However, part of the problem seems to be in this function:

    Function Uptime($ComputerName) #Function to calculate update of the given host.
    
    # . . .
    
    $ComputerName.ToUpper()
    

    Your $ComputerName parameter is not typed, so anything could be passed in (including $null). However, since you're calling ToUpper() on it, you clearly intended for this parameter to be a string. You should declare the types of your parameters (and in this case, perhaps even mark it as Mandatory). You probably also have a problem somewhere in the code that's calling the Uptime function, since it's not supposed to be passed null or empty string values.

    Function Uptime
    {
        param (
            [Parameter(Mandatory = $true)]
            [string] $ComputerName
        )
    }
    
  • #24402
    Profile photo of
    Anonymous

    hmm, but its running fine in PS 4.0 !! any clue for this?

  • #24404
    Profile photo of Dave Wyatt
    Dave Wyatt
    Moderator

    Ah, I was only looking at the null-valued expression screenshot. The divide by zero thing comes from trying to access a .Count property on either a $null value, or a single object which doesn't already have a .Count. In PowerShell 3.0 and later, they made this work ($null.Count is zero, (5).Count is 1, and any collection just returns its actual count.)

    To be PowerShell 2.0 compatible, the easiest way to manage this is to use the array subexpression operator, probably on this line:

    #This:
    
    $Exception_User_Input = $Exception_User_Input | Select-Object -Uniq
    
    # becomes this:
    
    $Exception_User_Input = @($Exception_User_Input | Select-Object -Uniq)
    

    By wrapping the expression in @(), you will get an array every time (which may contain zero, one, or multiple objects), and then you can reliably use the .Count property on it.

  • #24405
    Profile photo of Rob Simmers
    Rob Simmers
    Participant

    I think your issue is where you are doing .Count. If the object you are counting is only a single record, Powershell does not make it an array that contains a Count, I believe it's non-Scalar if my memory is correct. Basically, you should convert your objects to an array to ensure Count is not empty:

    @(myobject).Count

    I believe it was supposed to be fixed in later versions, but I still typically do it in my production scripts just to have backwards compatibility.

  • #24406
    Profile photo of
    Anonymous

    wow wow wow wow wow !! thnx a lot Wyatt. It worked. I was breaking my head from past 4 days.
    Thanks to PowerShell.Org 🙂

You must be logged in to reply to this topic.