Link to home
Start Free TrialLog in
Avatar of Chad K
Chad K

asked on

Watch directory in Windows 2012 Server and run elevated powershell when files appear.

Hello-

I have a little local intranet website which creates <temp>.tmp files on the system.  Those files contain simple powershell commands which are to be run against the system.  What i want to do is monitor the c:\temp directory on the webserver and when it sees a file in there, process those files running the commands one at a time in powershell with elevated privileges.  I have this working now using another powershell script which watches the directory, but it fails when a bunch of files are put in there all at once and is generally flaky.  I am fine with a commercial product to be used to watch the directory, but haven't found anything that works well in Windows 2012 Server.  Essentially the powershell should only fire when a file is "changed" as the website creates the temp file, then adds the commands to it, then saves it.  It all happens with a second or so, but I would want to be sure the file is complete before processing it.  Can anyone help?  I would also like to log the transactions to a file upon processing.
Avatar of Adam Brown
Adam Brown
Flag of United States of America image

Simple enough. Create a scheduled task that checks regularly and runs this:

 $file = dir <filepathandname> 
if ($file -ne $null)
{
 <run each command by calling the PS1 files>
}

Open in new window

There's no easy to use command line utility like inotifywait in Linux.

https://superuser.com/questions/226828/how-to-monitor-a-folder-and-trigger-a-command-line-action-when-a-file-is-created provides a simple example of how to write this code.
You can use Adam's approach too.

Just be sure to inject a sleep for some time in your loop, to guard against CPU spin.

Use Adam's approach if reaction time isn't really important.

Adam's approach has the benefit of being so simple anyone can understand the code, so a year from now if you come back to change something, changes will be more simple, than my solution.
It's possible to set the code I wrote into a loop to run the check constantly and only run the commands necessary if the temp file is found. This would check constantly and have a reaction time that would be nearly instantaneous, but I personally don't like having constant loops running like that, though you could certainly put a one second sleep in the loop to check once a second instead of constantly. That code would look like this:
while ($true){
     $file = dir <filepathandname> 
     if ($file -ne $null)
    {
          <run each command by calling the PS1 files>
     }
     start-sleep -s 1
}

Open in new window


The elevated privileges piece is fairly simple when you use a scheduled task to run this, as you can set the task to run even when the account is logged out, and once you create the task it will prompt for and store creds that will run the script.
Avatar of Chad K
Chad K

ASKER

Adam- I like this approach, but if the scheduled task gets hung for any reason, it would fail to work.  Is there any issue with running a cmd script like this from a scheduled task and expecting it to run all the time at login?
Avatar of Chad K

ASKER

Also, I won't know the filename from the script.  I will need to enumerate the path and grab the file names and pass to the "action" portion of the script?
ASKER CERTIFIED SOLUTION
Avatar of David Johnson, CD
David Johnson, CD
Flag of Canada image

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
Avatar of Chad K

ASKER

No issues with calling powershell from within powershell, David?  I would just schedule this script as a "run every X minutes" type thing and run it as the user with privileges I need?
Timing comes to mind as far as removing the existing files. A time stamp qualifier is needed in the script used to clean the folder so as to not delete newer files.
you can run powershell within powershell as you can run cmd..exe within cmd.exe
Avatar of Chad K

ASKER

That works.  I had to use Invoke-Expression and parse the files line by line, but it seems to work.  Thanks!