Require AD authentication before running script

This topic contains 11 replies, has 3 voices, and was last updated by Profile photo of Michael Orellana Michael Orellana 3 years, 4 months ago.

  • Author
    Posts
  • #11796
    Profile photo of Michael Orellana
    Michael Orellana
    Participant

    Hello,

    My name is michael and I am looking for a way to add AD authentication before my script is run. I am working with OS versions Windows Server 2003 & 2008, so I need this to be able to work across powershell v2 and v3. In theory I would like for powershell to check their credentials against our AD environment and if they exist and are true, run the rest of script.

    Any help would be greatly appreciated, I just signed up for this website yesterday so forgive me if I did not use the search feature (or just completely oblivious to where it is in the forum). : )

    Thanks again,
    Michael

  • #11797
    Profile photo of Don Jones
    Don Jones
    Keymaster

    The search box is in the right side of the main Forums page.

    The trick here, I think, is that you're going to have to have PowerShell try and DO something. There isn't a way (at least none I've seen that's straightforward) to "check" a credential. You have to try to do something, and then trap the error if it fails.

    You can use Get-Credential to prompt for a cred, but that won't validate it. You'd have to then USE that cred to try and perform some operation. Any command that has a -Credential parameter would accept a credential object produced by Get-Credential, and most commands will allow you to trap errors. So, very broadly:

    $cred = Get-Credential # in v3+ you can add a parameter that explains what the credential is for, so the user knows
    try {
      Get-ADUser -identity JohnD -credential $cred -ErrorAction Stop
    } catch {
      # did not work
    }
    

    So, if your domain doesn't allow anonymous users to query user objects, then this should fail if someone doesn't have permission to query. Most users have read permission to other users (so they can look up attributes like department and city). This is pretty broad as an example but hopefully will get you started.

  • #11798
    Profile photo of Dave Wyatt
    Dave Wyatt
    Moderator

    I'm not sure of a way to do this outside of your script, but there are several ways you could do it at the beginning of your script before running the rest of the code. Are you saying that you just want to make sure that the user who executed the script is an AD account?

  • #11799
    Profile photo of Michael Orellana
    Michael Orellana
    Participant

    [quote=11798]I'm not sure of a way to do this outside of your script, but there are several ways you could do it at the beginning of your script before running the rest of the code. Are you saying that you just want to make sure that the user who executed the script is an AD account?[/quote]

    Dave Wyatt, this is exactly what Im looking for.

  • #11801
    Profile photo of Dave Wyatt
    Dave Wyatt
    Moderator

    OK, there are a few ways you could do that. Here's one, off the top of my head:

    try
    {
        $null = [System.DirectoryServices.ActiveDirectory.Domain]::GetCurrentDomain()
    }
    catch
    {
        throw "Script must be executed as an Active Directory account."
    }
    
    # Continue with the rest of your script; if you get here, it's running as an AD user account.
    
  • #11802
    Profile photo of Michael Orellana
    Michael Orellana
    Participant

    Dave-

    Awesome! thank you, I will test it out and reply with my findings.

  • #11818
    Profile photo of Michael Orellana
    Michael Orellana
    Participant

    Alright it all appears to work fine and I appreciate the help very much, but would you mind elaborating a bit on how it all works. I have never used try catch throw, and im not all that certain as to what this line of code is doing

    "[System.DirectoryServices.ActiveDirectory.Domain]::GetCurrentDomain()"

  • #11819
    Profile photo of Dave Wyatt
    Dave Wyatt
    Moderator

    try/catch/finally is one of PowerShell's error handling options (specifically, for handling Terminating errors). There's a whole help file on that topic: about_Try_Catch_Finally.

    Throw is one of the ways you can produce a terminating error in your own scripts (and also has its own help file: about_Throw.)

    Documentation on the Domain.GetCurrentDomain method is here, but basically, it fetches information about the Active Directory domain of the currently logged on user. If you're not logged on with a domain account, it throws an exception (which you can catch with PowerShell's try/catch statements.)

  • #11820
    Profile photo of Michael Orellana
    Michael Orellana
    Participant

    awesome man, thank you so much for the help. One more question, and sorry to drag this topic on for so long, but what if we wanted to check if the user currently logged in, was associated with a particular AD group, which in turn would give access to run the script, so we dont have all AD users in our environment having the ability to run it.

  • #11821
    Profile photo of Dave Wyatt
    Dave Wyatt
    Moderator

    Since you're only verifying the group membership of the currently logged-on user, the fastest way would be to look at their logon token (which doesn't require any new lookups in the domain itself, other than to resolve the group's name to a SID.) For example:

    $groupName = [System.Security.Principal.NTAccount] 'DOMAIN\Group'
    $groupSid = $groupName.Translate([System.Security.Principal.SecurityIdentifier])
    
    if ([System.Security.Principal.WindowsIdentity]::GetCurrent().Groups -notcontains $groupSid)
    {
        throw 'No soup for you!'
    }
    
  • #11822
    Profile photo of Michael Orellana
    Michael Orellana
    Participant

    Dave!

    Youre the man! You have helped me greatly, much appreciated.

  • #11939
    Profile photo of Michael Orellana
    Michael Orellana
    Participant

    Everything worked great, thank you so much for the help.

You must be logged in to reply to this topic.