locked
[PowerShell] Retry with elevated credentials RRS feed

  • Question

  • I have several scripts where I attempt something in a Try{} block.  I catch various Access Denied exceptions in the Catch{} block.  In the Catch{} block, I first prompt for alternate credentials and then retry the same command again but with the addition of the -Credential parameter.  For example:

    Try
    {
        Remove-ADGroupMember -Identity $Group -Members $Members -Confirm:$false -ErrorAction Stop
    }
    Catch [Microsoft.ActiveDirectory.Management.ADException]
    {
        If ($Credentials -eq $null)
        {
            Write-Warning 'Access rights for the current session are insufficent. Please enter credentials that have access to modify group membership.'
            $Credentials = Get-Credential $null
        }
    
        Remove-ADGroupMember -Identity $Group -Members $Members -Confirm:$false -Credential $Credentials
    }


    This creates problems for script maintenance and bug fixing as I have to modify the same code twice in two different places.  I'd much rather do something like this (fake script):

    Function Remove-FromGroup($Group,$Members,$Credentials)
    {
        Remove-ADGroupMember -Identity $Group -Members $Members -Confirm:$false -Credential $Credentials
    }
    
    # Get the current user session credentials and store them in a variable.
    $Credentials = Get-CurrentUserSessionCredential
    
    Try
    {
        Remove-FromGroup $Group $Members $Credentials
    }
    Catch [Microsoft.ActiveDirectory.Management.ADException]
    {
        Write-Warning 'Access rights for the current session are insufficent. Please enter credentials that have access to modify group membership.'
    
        # Prompt the user to enter different credentials.
        $Credentials = Get-Credential $null
    
        Remove-FromGroup $Group $Members $Credentials
    }

    In this case, the actual code to remove users from a group only has to be maintained in a single place: the Remove-FromGroup function; however, it assumes there is a way to set the Credential parameter to the current user's PowerShell session credentials without prompting them.  In my example I am doing that by setting the $Credentials variable with a mythical Get-CurrentUserSessionCredential cmdlet.

    Is there is some method of doing what I'm looking for?  It doesn't have to be the logic like I have above. I'm just looking for some way to try to do something and if it doesn't work due to Access Denied, prompt for different credentials and try the same thing again with the other credentials, but only have the code for the thing to try written once.  Thanks.




    Tuesday, March 24, 2015 8:24 PM

Answers

  • Hi Scott,

    Found something else as well that should solve your problem.

    There is something called PowerShell call operator "&".  and PowerShell Invoke-Expression cmdlet.

    These allows you  Storing and executing a cmdlet in a variable

    Small Test Scripts below:

    $TestCMD = "Get-Process"
    Invoke-Expression $TestCMD
    "------------------------------------------------"
    $TestCMD += "| Sort-Object -Property Id"
    Invoke-Expression $TestCMD


    $TestCMD = "Get-Process"
    Invoke-Expression $TestCMD
    
    $a = 1
    
    do
    {
    
    If($a -eq 4)
     {
       "------------------------------------------------"
       $TestCMD += "| Sort-Object -Property Id"
       Invoke-Expression $TestCMD
    
     }
    
    
    $a++
    
    }While($a -le 5)
    

    Here goes your script function using the same utility:

    Function Remove-FromGroup($Group,$Members,$Credentials)
    {
    
    $RemoveCMD = "Remove-ADGroupMember -Identity $Group -Members $Members -Confirm:$false"
    
    if ($Credentials -eq $null)
    {
    Invoke-Expression $RemoveCMD
    }
    else
    {
    #Keeping the original cmdlet statement intact so that it can be used again without -Credential
    $temp = $RemoveCMD + " -Credential $Credentials"
    Invoke-Expression $temp
    }
    }

    Refernces:

    Execute cmdlet out of a variable

    Powershell - Storing and executing a cmdlet in a variable


    Regards,

    Satyajit

    Please “Vote As Helpful” if you find my contribution useful or “Mark As Answer” if it does answer your question. That will encourage me - and others - to take time out to help you.

    • Proposed as answer by Satyajit321 Monday, May 4, 2015 11:54 AM
    • Marked as answer by Boe ProxMVP Sunday, July 26, 2015 3:33 AM
    Wednesday, April 29, 2015 10:57 AM

All replies

  • Hi Scott,

    Dynamically creating the cmdlet statement is what you are looking for. Seems to be a bit complex.

    If your code is just the Remove-Group you can continue using it in 2 parts.

    Small addition that you can have is using a loop. Depends on how many times you want to prompt for invalid credentials (3 maybe).  Its not right calling the Remove function inside the Catch block. What happens if, it fails there as well.

    Function Remove-FromGroup($Group,$Members,$Credentials)
    {
    if ($Credentials -eq $null)

    {

    Remove-ADGroupMember -Identity $Group -Members $Members -Confirm:$false

    }

    else

    {

    Remove-ADGroupMember -Identity $Group -Members $Members -Confirm:$false -Credential $Credentials

    }

    }

    $Pass = 0 $Count = 0 $Credentials = $null do { try { Remove-FromGroup $Group $Members $Count $Credentials #For failed cases below lines will not execute #Write-Host "I'm I visible" $Pass = 1 } catch [Microsoft.ActiveDirectory.Management.ADException] { Write-Warning 'Access rights for the current session are insufficent. Please enter credentials that have access to modify group membership.'

     $count++

    if ($count -le 2)

    {

    # Prompt the user to enter different credentials.  $Credentials = Get-Credential $null

    }

    } }while($count -le 2 -AND $pass -ne 1)



    Regards,

    Satyajit

    Please“Vote As Helpful” if you find my contribution useful or “MarkAs Answer” if it does answer your question. That will encourage me - and others - to take time out to help you.




    • Edited by Satyajit321 Wednesday, April 29, 2015 10:58 AM
    Wednesday, April 29, 2015 9:47 AM
  • Hi Scott,

    Found something else as well that should solve your problem.

    There is something called PowerShell call operator "&".  and PowerShell Invoke-Expression cmdlet.

    These allows you  Storing and executing a cmdlet in a variable

    Small Test Scripts below:

    $TestCMD = "Get-Process"
    Invoke-Expression $TestCMD
    "------------------------------------------------"
    $TestCMD += "| Sort-Object -Property Id"
    Invoke-Expression $TestCMD


    $TestCMD = "Get-Process"
    Invoke-Expression $TestCMD
    
    $a = 1
    
    do
    {
    
    If($a -eq 4)
     {
       "------------------------------------------------"
       $TestCMD += "| Sort-Object -Property Id"
       Invoke-Expression $TestCMD
    
     }
    
    
    $a++
    
    }While($a -le 5)
    

    Here goes your script function using the same utility:

    Function Remove-FromGroup($Group,$Members,$Credentials)
    {
    
    $RemoveCMD = "Remove-ADGroupMember -Identity $Group -Members $Members -Confirm:$false"
    
    if ($Credentials -eq $null)
    {
    Invoke-Expression $RemoveCMD
    }
    else
    {
    #Keeping the original cmdlet statement intact so that it can be used again without -Credential
    $temp = $RemoveCMD + " -Credential $Credentials"
    Invoke-Expression $temp
    }
    }

    Refernces:

    Execute cmdlet out of a variable

    Powershell - Storing and executing a cmdlet in a variable


    Regards,

    Satyajit

    Please “Vote As Helpful” if you find my contribution useful or “Mark As Answer” if it does answer your question. That will encourage me - and others - to take time out to help you.

    • Proposed as answer by Satyajit321 Monday, May 4, 2015 11:54 AM
    • Marked as answer by Boe ProxMVP Sunday, July 26, 2015 3:33 AM
    Wednesday, April 29, 2015 10:57 AM
  • Hi Scott,

    Any Updates.


    Regards,

    Satyajit

    Please “Vote As Helpful” if you find my contribution useful or “Mark As Answer” if it does answer your question. That will encourage me - and others - to take time out to help you.

    Monday, May 4, 2015 11:54 AM