Trying to create a function to unlock and reset a user's AD account.

This topic contains 5 replies, has 2 voices, and was last updated by Profile photo of Matt Bloomfield Matt Bloomfield 3 months, 4 weeks ago.

  • Author
    Posts
  • #50055
    Profile photo of Christopher Michael
    Christopher Michael
    Participant

    So I have a script that works perfectly. I am trying to turn this script into a function so I can run it directly from the console. My current script uses VB to have a popup window for user input. I am trying to modify this. This is what I have so far. The first script is the one that doesn't work. The second one works I just want it to be a function. I want it to work by either accepting -username switch OR asking for it if you don't use the switch. Currently it is doing both

    function Unlock-User {
        [CmdletBinding()]
        param(
            [Parameter(Mandatory=$True)]
            [ValidateNotNullOrEmpty()]
            [string[]]$username
        )
         PROCESS {
            #$username = Read-Host -Prompt 'Input Username'
            $words = @('Red','Orange','Yellow','Green','Blue','Purple','White','Black')
            $word = $words | Get-Random
            $number = '{0:D2}' -f (Get-Random -Maximum 99)
            $password="$word$number"
    
            Unlock-ADAccount -Identity $username
            Set-ADAccountPassword -Identity $username -NewPassword (ConvertTo-SecureString -AsPlainText "$password" -Force)
            Set-ADUser -Identity $username -ChangePasswordAtLogon $true -PasswordNeverExpires $false
            Write-Output "User account $username has been unlocked, and password has been reset to $password"
        }
        END {}
    }
    
    
    
    
    
    ##################################################################
    ###
    ###
    ###
    ###
    ###
    ### This code unlocks a user account and resets the password. 
    ### It includes capitals, lowercase, and numbers. Easy to remember. 
    ### 
    ###
    ###
    ###
    ##################################################################
    
    
    
    
    
    ######################################################################
    ### I don't know what this does but it hides the PowerShell window ###
    ######################################################################
    
    $t = '[DllImport("user32.dll")] public static extern bool ShowWindow(int handle, int state);'
    add-type -name win -member $t -namespace native
    [native.win]::ShowWindow(([System.Diagnostics.Process]::GetCurrentProcess() | Get-Process).MainWindowHandle, 0)
    
    
    ##############################
    ### Load Visual Basic Shit ###
    ##############################
    
    [System.Reflection.Assembly]::LoadWithPartialName('Microsoft.VisualBasic')
    Add-Type -AssemblyName PresentationCore,PresentationFramework
    
    
    ###########################################################
    ### Make buttons, icons, and textbox for easier reading ###
    ###########################################################
    
    $ButtonType = [System.Windows.MessageBoxButton]::OK
    $MessageIcon = [System.Windows.MessageBoxImage]::Information
    $MessageTitle = "Account Unlocked!"
    
    
    ###########################
    ### Ask for a user name ###
    ###########################
        
    $username = [Microsoft.VisualBasic.Interaction]::InputBox("Enter a username", "Username")
    
    
    #######################
    ### Word dictionary ###
    #######################
        
    $words = @('Red','Orange','Yellow','Green','Blue','Purple','White','Black')
       
    
    ##########################
    ### Pick a random word ###
    ##########################
    
    $word = $words | Get-Random
    
    
    #########################################
    ### Get a random number with 2 digits ###
    #########################################
    
    $number = '{0:D2}' -f (Get-Random -Maximum 99)
    
    
    #############################
    ### Build password string ###
    #############################
    
    $password="$word$number"
    
    
    #########################
    ### Unlock AD account ###
    #########################
    
    Unlock-ADAccount -Identity $username
    
    
    #######################################
    ### Reset password and force change ###
    #######################################
    
    Set-ADAccountPassword -Identity $username -NewPassword (ConvertTo-SecureString -AsPlainText "$password" -Force)
    Set-ADUser -Identity $username -ChangePasswordAtLogon $true -PasswordNeverExpires $false
    
    
    ########################
    ### Message box text ###
    ########################
    
    $MessageBody = "User account $username has been unlocked, and password has been reset to $password"
    
    
    ############################
    ### Display confirmation ###
    ############################
    
    [System.Windows.MessageBox]::Show($MessageBody,$MessageTitle,$ButtonType,$MessageIcon)
  • #50072
    Profile photo of Matt Bloomfield
    Matt Bloomfield
    Participant

    You're nearly there.
    Your problem with the parameter is probably due to the way you're running the script. Try to dot source it with

    . c:\unlockscript.ps1

    You can then use

    Unlock-User -Username 'bob'

    You have a couple of other problems to fix:
    you're passing an array of strings to Unlock-AdAccount and it won't like that.
    you're telling the user that the password reset and unlock were successful, even if you get errors because of problem one.

  • #50084
    Profile photo of Christopher Michael
    Christopher Michael
    Participant

    So I am a little confused on what dot sourcing does. I remember reading about it but I am still confused

  • #50136
    Profile photo of Matt Bloomfield
    Matt Bloomfield
    Participant

    It's all to do with scope.

    Get-Help about_Scopes

    The console is your local scope.
    When you run a script from the console, the functions and variables run within the script scope. By default, the local scope (the console) doesn't know about your functions or variables in the script scope.
    When you dot source the script, it adds the functions and variables to the local scope so the functions and variables in the script can now be run from the console.

  • #50154
    Profile photo of Christopher Michael
    Christopher Michael
    Participant

    So say I had two console windows open and I didn't dot source. The function would only be on the one that I ran the script on and not the other one because it is self contained?

  • #50239
    Profile photo of Matt Bloomfield
    Matt Bloomfield
    Participant

    Each PowerShell console is self-contained, yes. When you start a new PowerShell instance a new global scope is created.

You must be logged in to reply to this topic.