In this article, I will discuss two simple methods to improve PowerShell remoting security. The first is by temporarily increasing the local administrator privileges. The second is by changing the password automatically in the script.

One of the aspects of PowerShell I use the most is running remote tasks on many computers at once. Using Invoke-Command, admins can easily and quickly perform tasks on remote computers by running it from one computer and "fanning" out to many at once. It is in my opinion one of the great features of PowerShell and is a great improvement from the old PSExec technique.

Although PowerShell encrypts all remote communication via Kerberos by default in a domain environment, I like to add in some additional security. It helps me sleep at night, which at many times is when these tasks are running.

In my example scenario, I want to run a script that uses Invoke-Command to restart the Windows Update service on remote machines. Here is the part of the script that does this:

Fairly simple, right? Now let's add some security to this script.

Temporarily increasing privileges ^

Restarting services requires local administrator access, so the account we will use to remote to these machines must have that. Many times sysadmins will just keep an account in the local administrator group at all times and use it when needed.

This of course is bad practice if you think about it. If this account is compromised, it now has access to any machine that has that account in the local administrator group. For this reason, why not use PowerShell to increase the permissions needed for this account when the script runs and then remove them when the script finishes?

One way to use this method is to have an Active Directory security group, in this case Local-Admins. We will add this group to the local administrators group on machines we want to install software to, thus giving any account in this group local administrator access to remote machines. In our case we will use an account (Dan) that has no special privileges in the domain.

After completing Invoke-Command, we will remove Dan from the Local-Admins security group, which will remove the local administrator permission for this account. With this method, the account used only has local administrator privileges during the execution of the script. This means if the account is compromised, the attacker has a much lesser chance of using it to do harm.

To make these changes we use the Active Directory cmdlets Add-ADGroupMember and Remove-ADGroupMember in our script.

Keep in mind the account executing the script will require permissions to add/remove users in Active Directory security groups in addition to resetting the password.

Automating password reset ^

Another important aspect of running PowerShell scripts that execute remote tasks is automating the credential used in Invoke-Command for the account you will use to authenticate and execute to the remote computers.

There are several ways to do this, but I prefer to reset a new password for the account I will be authenticating to remote machines with prior to Invoke-Command, and then reset it again when Invoke-Command is finished. With the use of PowerShell, this process is simple. Using this method, even if someone steals the password, the script will change it right after it completes, likely making it obsolete.

I will place this in a PowerShell function named Reset-InvokePassword. Another part of this function is creating a random password. For this, I used the script by Simon Wahlin on TechNet.

Combining everything into a PowerShell script ^

Now that I have provided some insight into the security for this remoting script, let us look at the code and output. I placed the code into a PowerShell script called RestartServices.

PowerShell script to restart remote services

PowerShell script to restart remote services

Since I use functions for creating and resetting the password for the account Dan, there is not much in the script itself. First, it adds the Dan account to the Local-Admins security group (which is nested within the local administrators group on our remote machines). Next, we reset the password while simultaneously putting it in a credential object.

We use Invoke-Command with that credential to connect to remote machines and restart the Windows Update service. Finally, we reset the Dan password again and remove it from the Local-Admins Active Directory group, thus removing administrator privileges on the remote machines. The idea with these methods is to create a moving target for this account, which decreases the likelihood of a breach.

Join the 4sysops PowerShell group!

Your question was not answered? Ask in the forum!


Users who have LIKED this post:

  • avatar
  1. James O'Neill 2 years ago

    I'd say this is really not good practice .

    In a large organization where the server which validates the logon to the remote is in a different site from the one where the group membership change was made the remote session may start before the AD update has propagated meaning the user will be not be seen as member of the elevated group.
    If multiple admins run the same script (and we don't want to have different admins using different scripts for the same task) each one logs on to remote server using the same proxy account. So auditing on that server won't show who made a change.
    If many admins use these scripts, it's quite possible which one that takes a long time to run and talks to many servers will find the password has changed because another admin ran it.
    You have a set of users who get full admin access to the remote machine.  Instead of doing this by giving their AD accounts access (as admin, or ideally to a constrained end point where they can a subset of commands in an account context whose credentials they don't see), you're giving them rights to add accounts to a group as a kind of back door and obfuscating the method of access but rather than limiting it. Unless you have some method for checking users haven't been left in the group  there is always a risk that some admins will add their accounts to it so they can quickly issue a one-liner.


    • James, I think you misunderstood the purpose of this method. The point is not to give other admins more rights temporarily. The idea is that you give yourself admin rights only when you really need them. Instead of keeping your account in the admin group, you only add it when you need the rights for the task. Because you have to provide credentials for adding an account to the admin group, this certainly improves security. This is comparable to entering su on a Linux machine.


  2. Derek Luk 2 years ago

    PowerShell Just Enough Administration should be a better solution than this method. As long as you are on PowerShell 5.1, you are set. You can limit the session and role access. Role configuration controls what cmdlet the user account can execute. Session configuration controls who has session access.


    • Session configurations are too complicated for this purpose. If you just want to give your account temporary admin rights to get a certain job done, you don't want to figure out first how to modify the session configuration for this particular job. Session configurations are good if you want to restrict the rights of an admin for a long-term project, not if you quickly need admin rights on a machine.

      Compare this with the sudo and su command on Linux. If you quickly need root access to do a couple of admin things, you enter su. If you want that a user can run certain administrative commands for a project, you change the sudo configuration.


  3. Dennis Rutherford 2 years ago

    This still doesn't sound like a smart thing to do. It sounds like you are trying to do privilege separating by adding and removing a user to a group. The user already has access to modify group membership in the domain they might as well have domain admin rights but maybe only sometimes ? Just create a separate user account, then you can audit when the user logs in to that account. use RunAs locally to switch to that account, and then use invoke-command to use it's kerberos permissions to connect to remote machines.



Leave a reply

Your email address will not be published. Required fields are marked *


© 4sysops 2006 - 2020


Please ask IT administration questions in the forums. Any other messages are welcome.


Log in with your credentials


Forgot your details?

Create Account