SelfService Active Directory Powershell script

Hi everybody,

We have a need for self service portal in our IT department. We arranged after work shifts, and if I’m not near my VPN connected PC, I needed to unlock or reset user passwords, or give users the ability to have their mangers do that for them.

I needed unlock or password reset solution for users, that will trigger a script on mail recieve. So I searched for simillar powershell script, and I found it DeployHappiness AD Self Service Portal.
This blog show us how to send SMS to mail, but our provider does not have this kind of service.

Still, this gave me a logic of things, and how to connect ot Exhange via API on specific mailbox, and query that mailbox for specific mails.

Then I needed to make sure that only users from our Organization can request, and that the person requesting is direct or indirect manager of the user.

Example:

  • IT Admins
    • John
      • Dave
      • Julia
        • Peter
        • Sandra
      • Steve
    • Angela
      • David
      • Jeremy
        • Marco

IT admins can request Unlock or Reset for everybody
John can request Unlock or Reset for his group (Dave,Julia,Peter,Sandra), but not for himself or Angela’s group.
Angela can request Unlock or Reset for hers group (David,Jeremy,Marco), but not for herself or John’s group.
Julia can request Unlock or Reset for hers group (Peter,Sandra), but not for herself or Dave and Steve.
Jeremy can request Unlock or Reset for Marco, but not for himself or David.

(Hope you got it) Smiješak

 

Next on Prerequisites:

  • Create a user with mail adress
  • Create Recieve connector on Exchange for server that will host the script
  • On server that will host a script install Feature: Active Directory module for Window Powershell
  • Setup Active Directory Users Manager on Users Organization Tab (example)
  • Define Mail Subject and Body field (For me Subject = User for Unlock or rest, Body = what to do Unlock user or Reset password)
  • Create taks scheduler (run as user to which you send mail requests), triggers set to 5 minutes (more or less is up to you)

Script:
Explanations are in my script commented.

<#

Script for SelService AD


This script enables IT to unlock or reset passwords to AD users. Mangers can also request for theirs employees.


        Author: Luka Gros

        Website: blog.lukagros.com

        Email: luka@lukagros.com

        Date created: 20.Octobar.2015

        Last modified: 20.Octobar.2015

        Version: 1.1


    .LINK


        http://blog.lukagros.com

        https://twitter.com/lukagros


#>

####Parts of Script from http://deployhappiness.com/reset-user-passwords-with-ad-self-service-portal/#######

##############################################################Config##############################################################

$SmtpServer = "10.10.10.1"

$ResetEmail = "Reset Notification <reset.password@domain.com>"

$Username = "DOMAIN\user"

$Password = "Passw0rd"

$MailServer = "https://mail.domain.com/ews/exchange.asmx"

$ExchangeVersion = "Exchange2013" ##"Exchange2010_sp1"

####ALERT MAIL####################

$LoggingUser = "InformationMail@domain.com"

####NEW USER RESET PASSWORD######

$NewPassword = "Passw0rd" #You can also find function that creates random password, but we use ours default. And be careful of character length in GPO


#######Download for API assembley file is here: http://www.microsoft.com/en-us/download/details.aspx?id=35371 (There is 2.2 that works better with Exchange 2013)

[Reflection.Assembly]::LoadFile("C:\Program Files\Microsoft\Exchange\Web Services\2.2\Microsoft.Exchange.WebServices.dll")



##############################################################Config##############################################################


###############################Function that checks if requester is manager to user###############################

#######http://www.lazywinadmin.com/2014/10/powershell-who-reports-to-whom-active.html########

function Get-ADdirectReports

{

    PARAM ($SamAccountName)

    Get-Aduser -identity $SamAccountName -Properties directreports | %{

        $_.directreports | ForEach-Object -Process {

            # Output the current Object information

            Get-ADUser -identity $Psitem -Properties mail,manager | Select-Object -Property Name, SamAccountName, Mail, @{ L = "Manager"; E = { (Get-Aduser -iden $psitem.manager).samaccountname } }


            # Find the DirectReports of the current item ($PSItem / $_)

            Get-ADdirectReports -SamAccountName $PSItem

        }

    }

}#CLOSE SECTION function Get-ADdirectReports


###############################Connect to Exchange mailbox###############################

 $email = New-Object Microsoft.Exchange.WebServices.Data.ExchangeService([Microsoft.Exchange.WebServices.Data.ExchangeVersion]::Exchange2013)

 $email.Credentials = New-Object Net.NetworkCredential($Username, $Password)

 $uri=[system.URI] $MailServer

 $email.Url = $uri

 $inbox = [Microsoft.Exchange.WebServices.Data.Folder]::Bind($email,[Microsoft.Exchange.WebServices.Data.WellKnownFolderName]::Inbox)

###############################Connect to Exchange mailbox###############################


###############################Check if there are unread mails###############################

if ($inbox.UnreadCount -gt 0)

 {

        $PropertySet = new-object Microsoft.Exchange.WebServices.Data.PropertySet([Microsoft.Exchange.WebServices.Data.BasePropertySet]::FirstClassProperties)

        $PropertySet.RequestedBodyType = [Microsoft.Exchange.WebServices.Data.BodyType]::Text;

        # Set search criteria - unread only

        $SearchForUnRead = New-object Microsoft.Exchange.WebServices.Data.SearchFilter+IsEqualTo([Microsoft.Exchange.WebServices.Data.EmailMessageSchema]::IsRead, $false)

        $items = $inbox.FindItems($SearchForUnRead,10)  #return only 10 unread mail items


        Import-Module -Name ActiveDirectory


 ###############################CHECK IF UNREAD ITEMS - IF NOT END###############################

 foreach ($item in $items.Items)

 {

  # load the property set to allow us to view the body

 $item.load($PropertySet)


    #######Get Subject and Body fields###

        $getsubjecttext = $item.subject

        $getsubjecttext = $getsubjecttext+"*" #add right wildcard

        $getbodytext = $item.body

        $getsubjectuser = Get-ADUser -Filter {DisplayName -like $getsubjecttext -and employeetype -eq'1'} -Properties UserPrincipalName,SamAccountName,cn,DisplayName,mail

        If ($getsubjectuser -eq $null) #If IT cannot be found by full name, try by SamAccountName

            {

            $getsubjectuser = Get-ADUser -Filter {SamAccountName -like $getsubjecttext -and employeetype -eq'1'} -Properties UserPrincipalName,SamAccountName,cn,DisplayName,mail

            }


        $managerEmployeOK = '0' ##Reset Manager Flag


        #######Get-requestere###

        $address = $item.From.address

        $user = Get-ADUser -Filter {UserPrincipalName -eq $address} -Properties UserPrincipalName,SamAccountName,cn


  ###Reset Unlock nad Reset flags for every mail####

  $UnlockAccount = '0'

  $ResetpwdAccount = '0'

#######IF Keywords in body

  if (($item.body.text -Like "Unlock account*") -and $getsubjectuser -ne $null) #THIS IS STRICT OR PEOPLE WILL WRITE RUBBISH

        {

            $UnlockAccount = '1'

        }


  if ($item.body.text -Like "Reset Password" -and $getsubjectuser -ne $null -and $UnlockAccount -eq '0') #THIS IS STRICT OR PEOPLE WILL WRITE RUBBISH

        {

            $ResetpwdAccount = '1'

        }


#################################If requester is found GO - IF NOT do nothing#######################################

if($user -ne $null)

{

<# If user is under requester set flag $managerEmployeOK=1, if not send mail NO RIGHTS

#>

    $usersToDo = Get-ADDirectReports $user.SamAccountName

    foreach ($Name in $usersToDo)

    {

        if ($Name.SamAccountName -eq $getsubjectuser.SamAccountName)

            {

                #Write-Output $Name.SamAccountName

                $managerEmployeOK = '1'

            }

    }

####Allow IT admins######

If ($user.SamAccountName -eq 'userAdmin1' -or $user.SamAccountName -eq 'userAdmin2') ##You can write if userAdmin is in some AdminGroup that can send requests

    {

    $managerEmployeOK = '1'

    }

##################################


IF ($managerEmployeOK -eq 1)

{

###UNLOCK SECTION################################################################################

 if($UnlockAccount -eq '1')

    {

            ##The line below is commented for e-mail testing, no command is issued

            ###Unlock-ADAccount -identity $getsubjectuser.samaccountname


            ##Send MAIL TO $LoggingUser = "InformationMail@domain.com"###################################

            $body="

                <p style='font-family:arial'>User Account " + $getsubjectuser.cn + " (" + $getsubjectuser.SamAccountName + ") has been unlocked. Request was from: $address</p>

                <p>&nbsp;

                <p style='font-family:arial;font-size:12px;color:red'>Please do not respond to this automatic e-mail!</p>

                "

            send-mailmessage -to $LoggingUser -from $ResetEmail -subject "Action: User unlock requested!" -body $Body  -SmtpServer $SmtpServer -BodyAsHtml -Encoding UTF8


            ##Send MAIL TO Requester###################################

            $body="

                <p style='font-family:arial'>HI,</p>

                <p style='font-family:arial'>User " + $getsubjectuser.cn + " (" + $getsubjectuser.SamAccountName + ") has been unlocked.</p>

                <p>&nbsp;

                 <p style='font-family:arial;font-size:12px;color:red'>Please do not respond to this automatic e-mail!</p>

                "

            send-mailmessage -to $item.From.address -from $ResetEmail -subject "User is unlocked!" -body $Body -SmtpServer $SmtpServer -BodyAsHtml -Encoding UTF8


            ##SEND MAIL TO unlocked user###################################

                $body="

                <p style='font-family:arial'>Hi " + $getsubjectuser.cn + ",</p>

                <p style='font-family:arial'>User " + $user.cn + " (" + $item.From.address + ") has requested unlocking of your account.</p>

                <p style='font-family:arial'>Your account <b>" + $getsubjectuser.SamAccountName +"</b> is now unlocked</p>

                <p>&nbsp;

                 <p style='font-family:arial;font-size:12px;color:red'>Please do not respond to this automatic e-mail!</p>

                "

            send-mailmessage -to $getsubjectuser.mail -from $ResetEmail -subject "Your account has been unlocked!" -body $body -SmtpServer $SmtpServer -BodyAsHtml -Encoding UTF8

            $Unlock = $True



    }#UNLOCK CLOSE SECTION


###RESET SECTION################################################################################

 if($ResetpwdAccount -eq '1')

    {

                <#The line below is commented for e-mail testing, no command is issued

                ###Set-ADAccountPassword -identity $user.samaccountname -Reset -NewPassword (ConvertTo-SecureString -AsPlainText $NewPassword -Force) #Set users new password

                ###Unlock-ADAccount -identity $user.samaccountname #Probably user locked, so unlock

###Set-ADUser -Identity $user.samaccountname -ChangePasswordAtLogon $true #Set must change password on next logon

                #>

                ##If the password was reseted in the last 10 minutes do nothing

                $PasswordAge = (Get-ADUser $getsubjectuser -Properties PasswordLastSet | Select PasswordLastSet)

                if ((Get-Date).AddMinutes(-10) -ge $PasswordAge.PasswordLastSet)

                 {


                ##Send MAIL TO $LoggingUser = "InformationMail@domain.com"###################################

                    $body="

                        <p style='font-family:arial'>Request for password reset for user " + $getsubjectuser.cn + " (" + $getsubjectuser.SamAccountName + "). Request was from: $address</p>

                        <p>&nbsp;

                        <p style='font-family:arial;font-size:12px;color:red'>Please do not respond to this automatic e-mail!</p>

                      "

                    send-mailmessage -to $LoggingUser -from $ResetEmail -subject "Action: User password reset requested!" -body $Body  -SmtpServer $SmtpServer -BodyAsHtml -Encoding UTF8


                    ##Send MAIL TO Requester###################################

                    $body="

                        <p style='font-family:arial'>Hi,</p>

                        <p style='font-family:arial'>Password reset for user" + $getsubjectuser.cn + " (" + $getsubjectuser.SamAccountName + ").</p>

                        <p style='font-family:arial'>New password is : <b>" + $NewPassword + "</b></p> ##If user cannot read their mail, then their manager can let them now

                        <p style='font-family:arial'>User can now try to logon with his/hers new password, but password must be changed on first logon!</p>

                        <p>&nbsp;

                        <p style='font-family:arial;font-size:12px;color:red'>Please do not respond to this automatic e-mail!</p>

                        "

                    send-mailmessage -to $item.From.address -from $ResetEmail -subject "Reset user password complete!" -body $Body -SmtpServer $SmtpServer -BodyAsHtml -Encoding UTF8


                    ##SEND MAIL TO user###################################

                    $body="

                        <p style='font-family:arial'>Hi " + $getsubjectuser.cn + ",</p>

                        <p style='font-family:arial'>User " + $user.cn + " (" + $item.From.address + ") requested your password to be changed. Your new password is: <b>" + $NewPassword +"</b></p>

                        <p>&nbsp;

                        <p style='font-family:arial;font-size:12px;color:red'>Please do not respond to this automatic e-mail!</p>

                           "

                    send-mailmessage -to $getsubjectuser.mail -from $ResetEmail -subject "Your password has been reseted!" -body $body -SmtpServer $SmtpServer -BodyAsHtml -Encoding UTF8

                } #CLOSE SECTION when was password last set

    }#CLOSE RESET SECITON


 ###Command or user unknown################################################################################

 if (($UnlockAccount -eq '0' -and $ResetpwdAccount -eq '0') -or ($getsubjectuser -eq $null))

    {

                        ##Send MAIL TO $LoggingUser = "InformationMail@domain.com"###################################

                        $body="

                        <p style='font-family:arial'>There was request " + $getsubjecttext +"; with body " + $getbodytext +"</p>

                        <p style='font-family:arial'>Request was  from: $address</p>

                        <p>&nbsp;

                        <p style='font-family:arial;font-size:12px;color:red'>Please do not respond to this automatic e-mail!</p>

                        "

                        send-mailmessage -to $LoggingUser -from $ResetEmail -subject "Action:request error" -body $Body  -SmtpServer $SmtpServer -BodyAsHtml -Encoding UTF8


                        ##Send MAIL TO Requester###################################

                        ##Don't forget here to write the instructions how the mail was supose to look

                        $body ="

                        <p style='font-family:arial'>Hi " + $user.cn + ",</p>

                        <p style='font-family:arial'>YOur mail, with title <b>" + $item.subject + "</b> is unknown.</p>

                        <p style='font-family:arial'>Please write correct user FirsName and Surname, or loginname.</p>

                        <p style='font-family:arial'>Keywords:</p>

                        <ul style='font-family:arial'>

                        <li><b>Unlock</b> - unlocks</li>

                        <li><b>Reset</b> - password reset</li>

                        </ul>

                        <p>&nbsp;

                        <p style='font-family:arial;font-size:12px;color:red'>Please do not respond to this automatic e-mail!</p>

                        "

                        send-mailmessage -to $item.From.address -from $ResetEmail -subject "Mail command unknown" -body $Body -SmtpServer $SmtpServer -BodyAsHtml -Encoding UTF8

      }#CLOSE SECTION Command or user unknown

} #CLOSE SECTION managerEmployeOK

else #If not manager

{

                        ##Send MAIL TO $LoggingUser = "InformationMail@domain.com"###################################

                        $body="

                        <p style='font-family:arial'>Stigao je mail sa naslovom <b>" + $getsubjecttext +"</b></p>

                        <p style='font-family:arial'>i tekstom <b>" + $getbodytext +"</b></p>

                        <p style='font-family:arial'>Zahtjev je došao sa adrese: $address</p>

                        <p>&nbsp;

                        <p style='font-family:arial;font-size:12px;color:red'>Please do not respond to this automatic e-mail!</p>

                        "

                        send-mailmessage -to $LoggingUser -from $ResetEmail -subject "Action:manager error" -body $Body  -SmtpServer $SmtpServer -BodyAsHtml -Encoding UTF8


                        ##Send MAIL TO Requester###################################

                        $body ="

                        <p style='font-family:arial'>Hi " + $user.cn + ",</p>

                        <p style='font-family:arial'>According to our specifications, you are not manager to user " + $getsubjectuser.cn + " (" + $getsubjectuser.SamAccountName + "). </p>

                        <p style='font-family:arial'>Request denied!</p>

                        <p>&nbsp;

                        <p style='font-family:arial;font-size:12px;color:red'>Please do not respond to this automatic e-mail!</p>

                        "

                        send-mailmessage -to $item.From.address -from $ResetEmail -subject "Manager request error" -body $Body -SmtpServer $SmtpServer -BodyAsHtml -Encoding UTF8

}#CLOSE SECTION if not manager

##Set mail read

$item.Isread = $true

$item.Update([Microsoft.Exchange.WebServices.Data.ConflictResolutionMode]::AlwaysOverwrite)


 }#CLOSE SECTION Requester OK

 } #CLOSE SECTION foreach ($item in $items.Items)

 } #CLOSE SECTION ($inbox.UnreadCount -gt 0)

 

So , this would be it.

How To remotely manage IIS from Client Computers

Several months ago we had one IIS server, and connecting to it over RDP was not a problem.

But now, since we got 4 IIS server on F5 NLB, Its quite problematic to connect to 4 IIS servers over RDP.
So I managed to install IIS administration, and I’m about to show you how.

First of all when installing IIS on the server, also check Management Service
image

When Installed

image

open IIS console, navigate to Management Service and open it.
image

image
Check Enable remote connections
If you plan to have local IIS managers, check Windows credentials or IIS Manager credentials
If you plan to manage IIS only with domain users, then check Windows credentials only

Leave IP address All Unassigned with manage port 8172 (IF YOU HAVE FIREWALL ENABLED, YOU MUST CREATE INBOUND RULE FOR THE PORT 8172)
For SSL certificate choose Server certificate (FQDN of the server)

And for more security, you can configure if you want to allow or deny some IP address on your LAN or WAN network. Depends from where are you planning to mange IIS.

When you completed the configuration, on the right side, press Apply ,and then Start.
One more step is to allow users to remotely connect to IIS server. Open IIS Manager Users.
image
image

For remote local admin users on IIS
On the right side press Add User.
User name: username
Password: Password from domain

This was configuration on the server, for more servers, repeat these steps on all of them. If you have NLB, you must do this on all of them!

Now, on the client side:
Go to Add Programs and Features and click on Turn Windows Features on or off
image
Click under Internet Information Services – Web Management Tools – IIS Management Console
image

After installation, download IIS Manager for Remote Administration 1.2, this gives you option to connect to remote server or site.
image
After installation, open your local IIS Manager, and connect to remote server:
image
image
Username must be entered with @domain.com suffix, or else it will return an error Unauthorised.
Enter domain password for that user.

Enter the name of connection
image

When done, you will have a list of remotely managed IIS servers.
image

Good Luck

Server – prevent registration of multiple IP to DNS from one server

 

I have a server with two IP addresses, one for internal network, one for external. But my server registers both IP addresses to DNS, and computers on internal network, sometimes get connection timeout.
The problem was solved when I disabled the DNS registration on the other NIC.

Go to TCP/IP v4 properties on NIC
image

Hit button Advanced
 image

In DNS tab remove check mark on Register this connection’s addresses in DNS
image 

now delete the A record, from DNS, with secondary IP and flushdns on computer with connection problem.

 

Good Luck