Sunday, February 9, 2020

Delete old files with Windows Task Scheduler and PowerShell script

1. Creating the PowerShell script.
2. Adding the task to the task scheduler.
3. Export the task to another machine.

1. Creating the PowerShell script. To delete files older than let's say 15 days we can use the following script
Get-ChildItem -Path C:\Logs -Include *.* -File -Recurse | Where-Object {($_.LastWriteTime -lt (Get-Date).AddDays(-15))} | foreach { $_.Delete()}
Note the the script deletes recursively files only, it doesn't touch folders, i.e. the folder structure is intact.

The problem with running PowerShell scripts via the Task Scheduler could be lack of permissions. That's why the best choice is to create self-elevating script.

# //This section is used to ensure we are running the script "As Administrator" so we don't get access denied errors when we run 
# //commands that require administrator permissions.
$myWindowsID=[System.Security.Principal.WindowsIdentity]::GetCurrent()
$myWindowsPrincipal=new-object System.Security.Principal.WindowsPrincipal($myWindowsID)
$adminRole=[System.Security.Principal.WindowsBuiltInRole]::Administrator
if ($myWindowsPrincipal.IsInRole($adminRole))
{
 Get-ChildItem -Path C:\Logs -Include *.* -File -Recurse | Where-Object {($_.LastWriteTime -lt (Get-Date).AddDays(-15))} | foreach { $_.Delete()}
 Get-ChildItem -Path D:\INC -Include *.* -File -Recurse | Where-Object {($_.LastWriteTime -lt (Get-Date).AddDays(-15))} | foreach { $_.Delete()}
 Get-ChildItem -Path C:\inetpub\ftproot\QAT -Include *.* -File -Recurse | Where-Object {($_.LastWriteTime -lt (Get-Date).AddDays(-15))} | foreach { $_.Delete()}
 Get-ChildItem -Path C:\inetpub\ftproot\TEST -Include *.* -File -Recurse | Where-Object {($_.LastWriteTime -lt (Get-Date).AddDays(-15))} | foreach { $_.Delete()}
 Get-ChildItem -Path C:\inetpub\logs\LogFiles -Include *.* -File -Recurse | Where-Object {($_.LastWriteTime -lt (Get-Date).AddDays(-15))} | foreach { $_.Delete()}
}
else
{
 # //We are not running "as Administrator" - so relaunch as administrator
 # //Create a new process object that starts PowerShell
 $newProcess = new-object System.Diagnostics.ProcessStartInfo "PowerShell";
 $newProcess.Arguments = $myInvocation.MyCommand.Definition;
 $newProcess.Verb = "runas";
 [System.Diagnostics.Process]::Start($newProcess);
 exit
}

So if the script is run under low permissions, it will rerun itself with full permissions. In the example above files from various loacations will be deleted.

2. Adding the task to the task scheduler. The task is pretty straightforward. The task scheduler new task master has plain set of steps, following through we create a new task. Specify the highest privilegies on the General tab:

Run the task every night:

Specify the PowerShell task on the Actions tab:

3. Export the task to another machine. That is the simple but very handy tip. If we need to have the same task on several machines, we can export the task as XML file. Just right-click on the task and choose Export. The XML file looks like following:

<?xml version="1.0" encoding="UTF-16"?>
<Task version="1.4" xmlns="http://schemas.microsoft.com/windows/2004/02/mit/task">
  <RegistrationInfo>
    <Date>2020-02-04T12:33:13.2575682</Date>
    <Author>%UserName%</Author>
    <Description>Deletes old foles like logs, uploads via FTP, Network etc.</Description>
    <URI>\DeleteOldFiles</URI>
  </RegistrationInfo>
  <Triggers>
    <CalendarTrigger>
      <StartBoundary>2020-02-06T01:00:00</StartBoundary>
      <Enabled>true</Enabled>
      <ScheduleByDay>
        <DaysInterval>1</DaysInterval>
      </ScheduleByDay>
    </CalendarTrigger>
  </Triggers>
  <Principals>
    <Principal id="Author">
      <GroupId>S-1-5-32-544</GroupId>
      <RunLevel>HighestAvailable</RunLevel>
    </Principal>
  </Principals>
  <Settings>
    <MultipleInstancesPolicy>IgnoreNew</MultipleInstancesPolicy>
    <DisallowStartIfOnBatteries>false</DisallowStartIfOnBatteries>
    <StopIfGoingOnBatteries>true</StopIfGoingOnBatteries>
    <AllowHardTerminate>true</AllowHardTerminate>
    <StartWhenAvailable>true</StartWhenAvailable>
    <RunOnlyIfNetworkAvailable>false</RunOnlyIfNetworkAvailable>
    <IdleSettings>
      <StopOnIdleEnd>true</StopOnIdleEnd>
      <RestartOnIdle>false</RestartOnIdle>
    </IdleSettings>
    <AllowStartOnDemand>true</AllowStartOnDemand>
    <Enabled>true</Enabled>
    <Hidden>false</Hidden>
    <RunOnlyIfIdle>false</RunOnlyIfIdle>
    <DisallowStartOnRemoteAppSession>false</DisallowStartOnRemoteAppSession>
    <UseUnifiedSchedulingEngine>true</UseUnifiedSchedulingEngine>
    <WakeToRun>false</WakeToRun>
    <ExecutionTimeLimit>PT1H</ExecutionTimeLimit>
    <Priority>7</Priority>
  </Settings>
  <Actions Context="Author">
    <Exec>
      <Command>powershell</Command>
      <Arguments>-File C:\DeleteOldFiles.ps1</Arguments>
    </Exec>
  </Actions>
</Task>

Then on another machine just import the task. And don't forger to copy the PS file as well..

No comments:

Post a Comment