Granting User Access Without Granting User Access in Windows

by Kevin Tai

I recently had a client who hired a consultant to work on a special project to update their website.  The client initially requested to allow the consultant access to a file share on the server where the website is hosted so that he can update the files.  Then the consultant realized that he needed additional access like restarting the services for the website’s Prod and Dev environments. We could’ve lazily grant him Remote Desktop access to the server and call it the day, but that would be giving him more access than he really needs.  All he really needs to do is to be able to restart 2 services (the production web server and the dev web server) after he makes updates to the environments.

That got me thinking that there must be an alternative way to accomplish this without giving up too much access.  So, I designed a process that would do just that and here’s how it works…

I wrote a PowerShell script that checks for the existence of a specific file at a specific location.  If that file exists, the script would restart a specific service (in this case, either the service for the production website or the service for the development website).  I added a scheduled task that would run this script every minute.

Now, let’s walk through the entire orchestration.

First step, we need to set up the “trigger” folder where the client would place the trigger file.  In this example, I use a folder named, “Restart_Web_Service” (it could be anything).

I also created 2 subfolders, “Dev” and “Prod”, where the specific trigger files live for their respective environment.  In Dev, I created an empty text file named, “webserver_dev_restart.txt”

In Prod, I have a similar file, but I named this one, “webserver_prod_restart.txt”

When the client needs to restart the web server service in the particular environment, they just simply copy the text file from that environment and paste it into the “Restart_Web_Service” folder.

In one minute or less, the scheduled task would run and the PowerShell script would detect that there’s a trigger file in the specific location and it will perform further actions (in this case, restart the web server service in the specified environment) if the file exists.

Here’s what the PowerShell Script looks like:

# Clean up previously created WebServer "restarted" file if exists.
$WSD_restarted = Test-Path -Path C:\Temp\Restart_Web_Service\webserver_dev_restarted.txt
If ($WSD_restarted -eq $True) { Del C:\Temp\Restart_Web_Service\webserver_dev_restarted.txt }
$WS_restarted = Test-Path -Path C:\Temp\Restart_Web_Service\webserver_prod_restarted.txt
If ($WS_restarted -eq $True) { Del C:\Temp\Restart_Web_Service\webserver_prod_restarted.txt }


# Checks the existence of the Dev trigger file.  If the file exists, restart the Dev service.
$WSD_restart = Test-Path -Path C:\Temp\Restart_Web_Service\webserver_dev_restart.txt  # Check the existence of the trigger file.
If ($WSD_restart -eq $True) {
     nssm stop WebServerDevService      # If the trigger file exists, restart the Dev instance of WebServer service.
     Start-Sleep -Seconds 5      # Pause the script for 5 seconds before starting the service.
     nssm start WebServerDevService      # Start the service.
     Del C:\Temp\Restart_Web_Service\webserver_dev_restart.txt    # This deletes the trigger file.
     New-Item C:\Temp\Restart_Web_Service\webserver_dev_restarted.txt -type file    # Place the "restarted" text file in the "Restart_Web_Service" folder to indicate that the service has been restarted.
     }

# Checks the existence of the Prod trigger file.  If the file exists, restart the Prod service.
$WS_restart = Test-Path -Path F:\WebKiosk_Admin\webserver_prod_restart.txt     # Check the existence of the trigger file.
If ($WS_restart -eq $True) {
     nssm stop WebServerProdService     # If the trigger file exists, restart the Prod instance of WebServer service.
     Start-Sleep -Seconds 5     # Pause the script for 5 seconds before starting the service.
     nssm start WebServerProdService     # Start the service.
     Del C:\Temp\Restart_Web_Service\webserver_prod_restart.txt    # This deletes the "webserver_prod_restart.txt" file.
     New-Item C:\Temp\Restart_Web_Service\webserver_prod_restarted.txt -type file    # Place the "restarted" text file in the "Restart_Web_Service" folder to indicate that the service has been restarted.
     }

Now, I’ve granted the user the ability to restart the web services without granting them the direct access to restart the services.  The only access I’ve granted them is the access to the shared folder that I created for them where they can place the trigger file. All the magic of restarting the service happens behind the scenes under different credentials.  You can use this similar methodology for allowing end users to perform other tasks without elevating their privileges.