Unhandled Exception when using break in function

Ask your Windows PowerShell-related questions, including questions on cmdlet development!
Forum rules
Do not post any licensing information in this forum.

Any code longer than three lines should be added as code using the 'Select Code' dropdown menu or attached as a file.
Locked
User avatar
Chris.Ediger
Posts: 42
Meble kuchenne na zamówienie - na wymiar - Wrocław
Joined: Tue Oct 24, 2017 9:33 am

Unhandled Exception when using break in function

Post by Chris.Ediger »

I have a function that I need to break out of if a certain condition error is encountered but I want the form to remain open so the user can retry the input. I used 'break' in my function which works as expected but I get an Unhandled exception "System error". How do I resolve the Unhandled exception error?

Thank you!

jvierra
Posts: 14358
Joined: Tue May 22, 2007 9:57 am
Contact:

Re: Unhandled Exception when using break in function

Post by jvierra »

To terminate a function we use "return" and not "break". "break" is for ending a loop iteration and can have unexpected impact when used incorrectly in a function.

Without the full error message it is truly impossible to know what is happening.

User avatar
Chris.Ediger
Posts: 42
Joined: Tue Oct 24, 2017 9:33 am

Re: Unhandled Exception when using break in function

Post by Chris.Ediger »

I tried using return but it returned and started running the functions that were next in line as if the previous function didn't have an error.
My flow is

Tech clicks "Create User" button
Function 1 - Gets credentials. If credentials are incorrect 3x gives message to verify and try again
Function 2
Function ....
I need it to not run Functions after 1 if there is an error.

User avatar
Chris.Ediger
Posts: 42
Joined: Tue Oct 24, 2017 9:33 am

Re: Unhandled Exception when using break in function

Post by Chris.Ediger »

Full errror

See the end of this message for details on invoking
just-in-time (JIT) debugging instead of this dialog box.

************** Exception Text **************
System.Management.Automation.BreakException: System error.
at System.Management.Automation.Interpreter.ThrowInstruction.Run(InterpretedFrame frame)
at System.Management.Automation.Interpreter.EnterTryCatchFinallyInstruction.Run(InterpretedFrame frame)
at System.Management.Automation.Interpreter.EnterTryCatchFinallyInstruction.Run(InterpretedFrame frame)
at System.Management.Automation.Interpreter.EnterTryCatchFinallyInstruction.Run(InterpretedFrame frame)
at System.Management.Automation.Interpreter.Interpreter.Run(InterpretedFrame frame)
at System.Management.Automation.Interpreter.LightLambda.RunVoid1[T0](T0 arg0)
at System.Management.Automation.DlrScriptCommandProcessor.RunClause(Action`1 clause, Object dollarUnderbar, Object inputToProcess)
at System.Management.Automation.DlrScriptCommandProcessor.Complete()
at System.Management.Automation.CommandProcessorBase.DoComplete()
at System.Management.Automation.Internal.PipelineProcessor.DoCompleteCore(CommandProcessorBase commandRequestingUpstreamCommandsToStop)
at System.Management.Automation.Internal.PipelineProcessor.SynchronousExecuteEnumerate(Object input)
at System.Management.Automation.PipelineOps.InvokePipeline(Object input, Boolean ignoreInput, CommandParameterInternal[][] pipeElements, CommandBaseAst[] pipeElementAsts, CommandRedirection[][] commandRedirections, FunctionContext funcContext)
at System.Management.Automation.Interpreter.ActionCallInstruction`6.Run(InterpretedFrame frame)
at System.Management.Automation.Interpreter.EnterTryCatchFinallyInstruction.Run(InterpretedFrame frame)
at System.Management.Automation.Interpreter.EnterTryCatchFinallyInstruction.Run(InterpretedFrame frame)
at System.Management.Automation.Interpreter.Interpreter.Run(InterpretedFrame frame)
at System.Management.Automation.Interpreter.LightLambda.RunVoid1[T0](T0 arg0)
at System.Management.Automation.ScriptBlock.InvokeWithPipeImpl(ScriptBlockClauseToInvoke clauseToInvoke, Boolean createLocalScope, Dictionary`2 functionsToDefine, List`1 variablesToDefine, ErrorHandlingBehavior errorHandlingBehavior, Object dollarUnder, Object input, Object scriptThis, Pipe outputPipe, InvocationInfo invocationInfo, Object[] args)
at System.Management.Automation.ScriptBlock.<>c__DisplayClass57_0.<InvokeWithPipe>b__0()
at System.Management.Automation.Runspaces.RunspaceBase.RunActionIfNoRunningPipelinesWithThreadCheck(Action action)
at System.Management.Automation.ScriptBlock.InvokeWithPipe(Boolean useLocalScope, ErrorHandlingBehavior errorHandlingBehavior, Object dollarUnder, Object input, Object scriptThis, Pipe outputPipe, InvocationInfo invocationInfo, Boolean propagateAllExceptionsToTop, List`1 variablesToDefine, Dictionary`2 functionsToDefine, Object[] args)
at System.Management.Automation.ScriptBlock.InvokeAsDelegateHelper(Object dollarUnder, Object dollarThis, Object[] args)
at System.Windows.Forms.Control.OnClick(EventArgs e)
at System.Windows.Forms.Button.OnClick(EventArgs e)
at System.Windows.Forms.Button.OnMouseUp(MouseEventArgs mevent)
at System.Windows.Forms.Control.WmMouseUp(Message& m, MouseButtons button, Int32 clicks)
at System.Windows.Forms.Control.WndProc(Message& m)
at System.Windows.Forms.ButtonBase.WndProc(Message& m)
at System.Windows.Forms.Button.WndProc(Message& m)
at System.Windows.Forms.NativeWindow.Callback(IntPtr hWnd, Int32 msg, IntPtr wparam, IntPtr lparam)


************** Loaded Assemblies **************
mscorlib
Assembly Version: 4.0.0.0
Win32 Version: 4.8.4150.0 built by: NET48REL1LAST_C
CodeBase: file:///C:/Windows/Microsoft.NET/Framework64/v4.0.30319/mscorlib.dll
----------------------------------------
DebuggerProxyV5
Assembly Version: 1.0.7338.39842
Win32 Version: 1.1.5.0
CodeBase: file:///C:/Program%20Files/SAPIEN%20Technologies,%20Inc/PowerShell%20Studio%202020/Debugger64/DebuggerProxyV5.DLL
----------------------------------------
PowerShellDebuggerV5
Assembly Version: 1.1.8.0
Win32 Version: 1.1.8.0
CodeBase: file:///C:/Program%20Files/SAPIEN%20Technologies,%20Inc/PowerShell%20Studio%202020/Debugger64/PowerShellDebuggerV5.DLL
----------------------------------------
System.Management.Automation
Assembly Version: 3.0.0.0
Win32 Version: 10.0.18362.628
CodeBase: file:///C:/WINDOWS/Microsoft.Net/assembly/GAC_MSIL/System.Management.Automation/v4.0_3.0.0.0__31bf3856ad364e35/System.Management.Automation.dll
----------------------------------------
System
Assembly Version: 4.0.0.0
Win32 Version: 4.8.4001.0 built by: NET48REL1LAST_C
CodeBase: file:///C:/WINDOWS/Microsoft.Net/assembly/GAC_MSIL/System/v4.0_4.0.0.0__b77a5c561934e089/System.dll
----------------------------------------
System.Core
Assembly Version: 4.0.0.0
Win32 Version: 4.8.4121.0 built by: NET48REL1LAST_C
CodeBase: file:///C:/WINDOWS/Microsoft.Net/assembly/GAC_MSIL/System.Core/v4.0_4.0.0.0__b77a5c561934e089/System.Core.dll
----------------------------------------
System.Windows.Forms
Assembly Version: 4.0.0.0
Win32 Version: 4.8.4150.0 built by: NET48REL1LAST_C
CodeBase: file:///C:/WINDOWS/Microsoft.Net/assembly/GAC_MSIL/System.Windows.Forms/v4.0_4.0.0.0__b77a5c561934e089/System.Windows.Forms.dll
----------------------------------------
System.Drawing
Assembly Version: 4.0.0.0
Win32 Version: 4.8.3752.0 built by: NET48REL1
CodeBase: file:///C:/WINDOWS/Microsoft.Net/assembly/GAC_MSIL/System.Drawing/v4.0_4.0.0.0__b03f5f7f11d50a3a/System.Drawing.dll
----------------------------------------
Microsoft.PowerShell.Commands.Diagnostics
Assembly Version: 3.0.0.0
Win32 Version: 10.0.18362.1
CodeBase: file:///C:/WINDOWS/Microsoft.Net/assembly/GAC_MSIL/Microsoft.PowerShell.Commands.Diagnostics/v4.0_3.0.0.0__31bf3856ad364e35/Microsoft.PowerShell.Commands.Diagnostics.dll
----------------------------------------
System.Configuration.Install
Assembly Version: 4.0.0.0
Win32 Version: 4.8.3752.0 built by: NET48REL1
CodeBase: file:///C:/WINDOWS/Microsoft.Net/assembly/GAC_MSIL/System.Configuration.Install/v4.0_4.0.0.0__b03f5f7f11d50a3a/System.Configuration.Install.dll
----------------------------------------
Microsoft.PowerShell.ConsoleHost
Assembly Version: 3.0.0.0
Win32 Version: 10.0.18362.1
CodeBase: file:///C:/WINDOWS/Microsoft.Net/assembly/GAC_MSIL/Microsoft.PowerShell.ConsoleHost/v4.0_3.0.0.0__31bf3856ad364e35/Microsoft.PowerShell.ConsoleHost.dll
----------------------------------------
Microsoft.PowerShell.Commands.Utility
Assembly Version: 3.0.0.0
Win32 Version: 10.0.18362.1
CodeBase: file:///C:/WINDOWS/Microsoft.Net/assembly/GAC_MSIL/Microsoft.PowerShell.Commands.Utility/v4.0_3.0.0.0__31bf3856ad364e35/Microsoft.PowerShell.Commands.Utility.dll
----------------------------------------
Microsoft.PowerShell.Commands.Management
Assembly Version: 3.0.0.0
Win32 Version: 10.0.18362.1
CodeBase: file:///C:/WINDOWS/Microsoft.Net/assembly/GAC_MSIL/Microsoft.PowerShell.Commands.Management/v4.0_3.0.0.0__31bf3856ad364e35/Microsoft.PowerShell.Commands.Management.dll
----------------------------------------
Microsoft.Management.Infrastructure
Assembly Version: 1.0.0.0
Win32 Version: 10.0.18362.1
CodeBase: file:///C:/WINDOWS/Microsoft.Net/assembly/GAC_MSIL/Microsoft.Management.Infrastructure/v4.0_1.0.0.0__31bf3856ad364e35/Microsoft.Management.Infrastructure.dll
----------------------------------------
Microsoft.PowerShell.Security
Assembly Version: 3.0.0.0
Win32 Version: 10.0.18362.1
CodeBase: file:///C:/WINDOWS/Microsoft.Net/assembly/GAC_MSIL/Microsoft.PowerShell.Security/v4.0_3.0.0.0__31bf3856ad364e35/Microsoft.PowerShell.Security.dll
----------------------------------------
Microsoft.WSMan.Management
Assembly Version: 3.0.0.0
Win32 Version: 10.0.18362.1
CodeBase: file:///C:/WINDOWS/Microsoft.Net/assembly/GAC_MSIL/Microsoft.WSMan.Management/v4.0_3.0.0.0__31bf3856ad364e35/Microsoft.WSMan.Management.dll
----------------------------------------
System.Configuration
Assembly Version: 4.0.0.0
Win32 Version: 4.8.3752.0 built by: NET48REL1
CodeBase: file:///C:/WINDOWS/Microsoft.Net/assembly/GAC_MSIL/System.Configuration/v4.0_4.0.0.0__b03f5f7f11d50a3a/System.Configuration.dll
----------------------------------------
System.Xml
Assembly Version: 4.0.0.0
Win32 Version: 4.8.3752.0 built by: NET48REL1
CodeBase: file:///C:/WINDOWS/Microsoft.Net/assembly/GAC_MSIL/System.Xml/v4.0_4.0.0.0__b77a5c561934e089/System.Xml.dll
----------------------------------------
System.Data
Assembly Version: 4.0.0.0
Win32 Version: 4.8.4121.0 built by: NET48REL1LAST_C
CodeBase: file:///C:/WINDOWS/Microsoft.Net/assembly/GAC_64/System.Data/v4.0_4.0.0.0__b77a5c561934e089/System.Data.dll
----------------------------------------
System.Management
Assembly Version: 4.0.0.0
Win32 Version: 4.8.3752.0 built by: NET48REL1
CodeBase: file:///C:/WINDOWS/Microsoft.Net/assembly/GAC_MSIL/System.Management/v4.0_4.0.0.0__b03f5f7f11d50a3a/System.Management.dll
----------------------------------------
System.DirectoryServices
Assembly Version: 4.0.0.0
Win32 Version: 4.8.3752.0 built by: NET48REL1
CodeBase: file:///C:/WINDOWS/Microsoft.Net/assembly/GAC_MSIL/System.DirectoryServices/v4.0_4.0.0.0__b03f5f7f11d50a3a/System.DirectoryServices.dll
----------------------------------------
Anonymously Hosted DynamicMethods Assembly
Assembly Version: 0.0.0.0
Win32 Version: 4.8.4150.0 built by: NET48REL1LAST_C
CodeBase: file:///C:/WINDOWS/Microsoft.Net/assembly/GAC_64/mscorlib/v4.0_4.0.0.0__b77a5c561934e089/mscorlib.dll
----------------------------------------
System.Transactions
Assembly Version: 4.0.0.0
Win32 Version: 4.8.3752.0 built by: NET48REL1
CodeBase: file:///C:/WINDOWS/Microsoft.Net/assembly/GAC_64/System.Transactions/v4.0_4.0.0.0__b77a5c561934e089/System.Transactions.dll
----------------------------------------
System.Numerics
Assembly Version: 4.0.0.0
Win32 Version: 4.8.3752.0 built by: NET48REL1
CodeBase: file:///C:/WINDOWS/Microsoft.Net/assembly/GAC_MSIL/System.Numerics/v4.0_4.0.0.0__b77a5c561934e089/System.Numerics.dll
----------------------------------------
Accessibility
Assembly Version: 4.0.0.0
Win32 Version: 4.8.3752.0 built by: NET48REL1
CodeBase: file:///C:/WINDOWS/Microsoft.Net/assembly/GAC_MSIL/Accessibility/v4.0_4.0.0.0__b03f5f7f11d50a3a/Accessibility.dll
----------------------------------------
Microsoft.ActiveDirectory.Management
Assembly Version: 10.0.0.0
Win32 Version: 10.0.18362.628
CodeBase: file:///C:/WINDOWS/Microsoft.Net/assembly/GAC_64/Microsoft.ActiveDirectory.Management/v4.0_10.0.0.0__31bf3856ad364e35/Microsoft.ActiveDirectory.Management.dll
----------------------------------------
System.DirectoryServices.Protocols
Assembly Version: 4.0.0.0
Win32 Version: 4.8.3752.0 built by: NET48REL1
CodeBase: file:///C:/WINDOWS/Microsoft.Net/assembly/GAC_MSIL/System.DirectoryServices.Protocols/v4.0_4.0.0.0__b03f5f7f11d50a3a/System.DirectoryServices.Protocols.dll
----------------------------------------
System.ServiceModel
Assembly Version: 4.0.0.0
Win32 Version: 4.8.4150.0 built by: NET48REL1LAST_C
CodeBase: file:///C:/WINDOWS/Microsoft.Net/assembly/GAC_MSIL/System.ServiceModel/v4.0_4.0.0.0__b77a5c561934e089/System.ServiceModel.dll
----------------------------------------
System.Runtime.Serialization
Assembly Version: 4.0.0.0
Win32 Version: 4.8.4150.0 built by: NET48REL1LAST_C
CodeBase: file:///C:/WINDOWS/Microsoft.Net/assembly/GAC_MSIL/System.Runtime.Serialization/v4.0_4.0.0.0__b77a5c561934e089/System.Runtime.Serialization.dll
----------------------------------------
SMDiagnostics
Assembly Version: 4.0.0.0
Win32 Version: 4.8.4150.0 built by: NET48REL1LAST_C
CodeBase: file:///C:/WINDOWS/Microsoft.Net/assembly/GAC_MSIL/SMDiagnostics/v4.0_4.0.0.0__b77a5c561934e089/SMDiagnostics.dll
----------------------------------------
System.ServiceModel.Internals
Assembly Version: 4.0.0.0
Win32 Version: 4.8.4150.0 built by: NET48REL1LAST_C
CodeBase: file:///C:/WINDOWS/Microsoft.Net/assembly/GAC_MSIL/System.ServiceModel.Internals/v4.0_4.0.0.0__31bf3856ad364e35/System.ServiceModel.Internals.dll
----------------------------------------
System.IdentityModel
Assembly Version: 4.0.0.0
Win32 Version: 4.8.4150.0 built by: NET48REL1LAST_C
CodeBase: file:///C:/WINDOWS/Microsoft.Net/assembly/GAC_MSIL/System.IdentityModel/v4.0_4.0.0.0__b77a5c561934e089/System.IdentityModel.dll
----------------------------------------

************** JIT Debugging **************
To enable just-in-time (JIT) debugging, the .config file for this
application or computer (machine.config) must have the
jitDebugging value set in the system.windows.forms section.
The application must also be compiled with debugging
enabled.

For example:

<configuration>
<system.windows.forms jitDebugging="true" />
</configuration>

When JIT debugging is enabled, any unhandled exception
will be sent to the JIT debugger registered on the computer
rather than be handled by this dialog box.

jvierra
Posts: 14358
Joined: Tue May 22, 2007 9:57 am
Contact:

Re: Unhandled Exception when using break in function

Post by jvierra »

How are you running this code and what is the code in the form event. The exception is being caused by the script. This is likely because you are using a break statement to exit an event, You must use a return statement to exit an function or event.

The last lines of the exception tells us that you are executing code that terminates the message loop.
System.Windows.Forms.NativeWindow.Callback(IntPtr hWnd, Int32 msg, IntPtr wparam, IntPtr lparam)
This is likely caused by the break statement.

Again. Without the code it is not possible to know what is happening. Just know that a "break" is not used to exit a function and it can have big issues in a form's event.

User avatar
Chris.Ediger
Posts: 42
Joined: Tue Oct 24, 2017 9:33 am

Re: Unhandled Exception when using break in function

Post by Chris.Ediger »

I have this function run in the context of my larger user creation function. When the user clicks my "Create User" button it calls a user creation function that has the Get-DomainAdminCredentials function first. After it gathers the (correct) credentials it goes on to do the rest of the stuff...
If I do a return instead of break it goes back to the parent function and continues running the other functions below it. Many ugly errors result :evil:
  1. function Get-DomainAdminCredentials
  2.  
  3. {
  4.  
  5.     $Authenticated = $true
  6.  
  7.     do
  8.  
  9.     {
  10.  
  11.         $Counter = 0
  12.  
  13.         do
  14.  
  15.         {
  16.  
  17.             if (($Counter -eq 3) -and ($Authenticated -eq $false))
  18.  
  19.             {
  20.  
  21.                 [void][System.Windows.Forms.MessageBox]::Show("Please verify domain administrator credentials and try again", "Verify Credentials", "OK", 'Stop')
  22.  
  23.                 $DomainAdminCredentials = "Username or Password Error"
  24.  
  25.                 break
  26.  
  27.             }
  28.  
  29.             else
  30.  
  31.             {
  32.  
  33.                 $DomainAdminCredentials = Get-Credential -Message "Enter Domain Admin Credentials"
  34.  
  35.                 $AdminUserName = $DomainAdminCredentials.UserName
  36.  
  37.                 $AdminPassword = $DomainAdminCredentials.GetNetworkCredential().Password
  38.  
  39.                 $CurrentDomain = "LDAP://" + ([adsi]"").DistinguishedName
  40.  
  41.                 $DomainObject = New-Object System.DirectoryServices.DirectoryEntry ($CurrentDomain, $AdminUserName, $AdminPassword)
  42.  
  43.                
  44.  
  45.                 if (!($DomainObject.Name))
  46.  
  47.                 {
  48.  
  49.                     [void][System.Windows.Forms.MessageBox]::Show("Username or Password Incorrect", "Warning", "OK", "Error")
  50.  
  51.                     $Counter++
  52.  
  53.                     $Authenticated = $false
  54.  
  55.                 }
  56.  
  57.                 else
  58.  
  59.                 {
  60.  
  61.                     $Authenticated = $true
  62.  
  63.                 }
  64.  
  65.             }
  66.  
  67.         }
  68.  
  69.         while
  70.  
  71.         (
  72.  
  73.             ($Counter -le 3) -and ($Authenticated -eq $false)
  74.  
  75.         )
  76.  
  77.     }
  78.  
  79.     while (
  80.  
  81.         $Authenticated = $false
  82.  
  83.     )
  84.  
  85.     $DomainAdminCredentials
  86.  
  87.    
  88.  
  89. }

jvierra
Posts: 14358
Joined: Tue May 22, 2007 9:57 am
Contact:

Re: Unhandled Exception when using break in function

Post by jvierra »

This is what it appears your code looks like.

Code: Select all

function Get-DomainAdminCredentials{
    $Authenticated = $true
    do{
        $Counter = 0
        do{
            if($Counter -eq 3 -and $Authenticated -eq $false){
                [void][System.Windows.Forms.MessageBox]::Show("Please verify domain administrator credentials and try again", "Verify Credentials", "OK", 'Stop')
                $DomainAdminCredentials = "Username or Password Error"
                break
            }else{
                $DomainAdminCredentials = Get-Credential -Message "Enter Domain Admin Credentials"
                $AdminUserName = $DomainAdminCredentials.UserName
                $AdminPassword = $DomainAdminCredentials.GetNetworkCredential().Password
                $CurrentDomain = "LDAP://" + ([adsi]"").DistinguishedName
                $DomainObject = New-Object System.DirectoryServices.DirectoryEntry ($CurrentDomain, $AdminUserName, $AdminPassword) 
                if (!($DomainObject.Name)){
                    [void][System.Windows.Forms.MessageBox]::Show("Username or Password Incorrect", "Warning", "OK", "Error")
                    $Counter++
                    $Authenticated = $false
                }else{
                    $Authenticated = $true
                }
            }
        }
        while($Counter -le 3 -and $Authenticated -eq $false)
    } 
    while($Authenticated = $false)
    
    $DomainAdminCredentials
}
It is a bit convoluted and is not using the break illegally however, it is not returning from the loop. It also appears that it can enter an endless loop condition which will eventually "blow the stack" and cause an exception or, more likely, an event in the form will cause an exception. It is really a bad idea to use endless loops in event code. This is one of the hardest lessons for aa non-programmer new to forms faces. The rule is : "Don't do it."

Forms are designed to allow you to create code that doesn't use loop processing techniques. Re-write the code to use a declarative approach to entering credentials. Use Try/Catch to detect when the credentials are wrong.

I see no reason why you are authenticating to the current domain. That is never necessary. If you need to run the script as an admin or other users just execute the script wit alternate credentials. You can do this with a shortcut or package as an EXE.

To just get a domain object with credentials the following is all that is necessary:

Code: Select all

$cred = Get-Credential -Message "Enter Domain Admin Credentials"
$domain = Get-AdDomain -Credential $cred
To do this three times and quit:

Code: Select all

for($i=1;$i -le 3; $i++){
     Try{
          $cred = Get-Credential -Message "Enter Domain Admin Credentials"
          $domain = Get-AdDomain -Credential $cred -ErrorAction Stop
          break
      }
     Catch{
          # try again message
     }
}
if($domain){ 
     # domain was authenticated
}
[/code]

User avatar
Chris.Ediger
Posts: 42
Joined: Tue Oct 24, 2017 9:33 am

Re: Unhandled Exception when using break in function

Post by Chris.Ediger »

I'm not a programmer at all. Everything I've done is self taught so I'm sure I'm doing a lot of things in a jankey sort of way. I do the best I can until it works.

jvierra
Posts: 14358
Joined: Tue May 22, 2007 9:57 am
Contact:

Re: Unhandled Exception when using break in function

Post by jvierra »

Chris.Ediger wrote:
Mon Mar 16, 2020 2:14 pm
I'm not a programmer at all. Everything I've done is self taught so I'm sure I'm doing a lot of things in a jankey sort of way. I do the best I can until it works.
All the more reason to spend time learning the technology. The programming will come a you begin to understand how the technology is designed to work.

You can get away with some things by guessing in a simple script. A form adds a technical complexity that tends to defeat pure guesswork and most blogs and forums that address forms are written by non-programmers using guesswork and copying code. The Sapien "info" site is better than most I have seen so it is a minimum resource that will help you to understand the way to use forms. Unfortunately there is no design documentation for forms and PowerShell.

The first rule of coding is to keep everything as simple as possible and test and understand each line of code. Build one line at a time at a prompt until you get the results you need. Your function should be tested as a function at a PS prompt until it behaves correctly.

Ask yourself why you need an indefinite set of loops to perform a simple set of three attempts at a result. "for()" does all of that in one line.

Basic programming is what you will learn with most of the better books on PowerShell. The Sapien free book is a good place to start if you remember that it is at PS3 and does not cover newer extensions from PS4 and PS5.

It is downloadable here: https://www.sapien.com/books_training/W ... werShell-4

Locked