1

I am writing a powershell script which shall periodically run to backup the contents of a remote folder. That remote folder is mapped as a WebDav share to my Windows drive G:\.

This post and this one say

  • that mapped drives cannot be accessed directly and
  • that they should be accessed via UNC.

Accessing the remote folder via UNC requires that I provide credentials. I don't want them lying around in plain text, so I try to access them via the Credentials Manager. I have thus done the installation of module CredentialManager, and now, getting the credentials and mounting the remote folder

  • works fine if I run the script manually (from within MS Code)
    • my powershell version is 7.3.6
  • fails if the script is run from the task scheduler though
    • the user is the same (see output of whoami), it is a non-admin account
    • the user has the "Logon as batch job" rights
    • run with highest privileges is not ticked
    • I tried both, Run whether user is logged on or not and Run only when user is logged on, but it makes no difference

Why is that and what can I do to get access to the remote folder from the scheduled script?

The script access.ps1:

# MAIN ########################################################################
$debuglog = $PSScriptRoot + "\" + "debuglog.txt"
#$debuglog = $null
$PSDefaultParameterValues = @{'Out-File:Encoding' = 'utf8'}   # https://stackoverflow.com/questions/64757125/how-to-specify-file-format-for-powershell-tee-command
                                                              # https://stackoverflow.com/questions/40098771/changing-powershells-default-output-encoding-to-utf-8
                                                              # https://stackoverflow.com/questions/30606929/tee-with-utf-8-encoding

Info:

echo "$(get-date -format 'yyMMdd-HHmmss') ##################################################" >> $debuglog echo "Which domain/account?: <$(whoami)>" >> $debuglog echo "Available drives:" $(get-psdrive) >> $debuglog

OK, when drive does not show up when script is run from task scheduler, then let's map it:

$credential = Get-StoredCredential -Target "webdav.mc.gmx.net" echo "Credential: $credential" >> $debuglog if ($credential) { echo "Credentials found." >> $debuglog
$username = $credential.UserName $password = $credential.GetNetworkCredential().Password

$driveLetter = "Y" $networkPath = "\webdav.mc.gmx.net@SSL\DavWWWRoot\myData&quot; remove-psdrive $driveLetter New-PSDrive -Name $driveLetter -PSProvider FileSystem -Root $networkPath -Credential $credential } else { echo "Accessing credentials failed." >> $debuglog
} echo "psdrives:" $(get-psdrive) >> $debuglog echo "Dir: " $(dir y:) >> $debuglog remove-psdrive $driveLetter

echo "Exit." >> $debuglog exit

The output of the script:

  • left: when run "manually", i.e. from MS Code
  • right: when run through the task scheduler
    • user names are identical
    • drive G:\ is not available
    • accessing credentials failed

enter image description here

The scheduler's XML:

<?xml version="1.0" encoding="UTF-16"?>
<Task version="1.4" xmlns="http://schemas.microsoft.com/windows/2004/02/mit/task">
  <RegistrationInfo>
    <Date>2023-07-31T23:41:50.6178473</Date>
    <Author>DELFIN7\Martin</Author>
    <URI>\Access2</URI>
  </RegistrationInfo>
  <Triggers>
    <CalendarTrigger>
      <StartBoundary>2023-07-31T23:40:09</StartBoundary>
      <Enabled>true</Enabled>
      <ScheduleByMonth>
        <DaysOfMonth>
          <Day>13</Day>
        </DaysOfMonth>
        <Months>
          <January />
          <February />
          <March />
          <April />
          <May />
          <June />
          <July />
          <August />
          <September />
          <October />
          <November />
          <December />
        </Months>
      </ScheduleByMonth>
    </CalendarTrigger>
  </Triggers>
  <Principals>
    <Principal id="Author">
      <UserId>S-1-5-21-48XXXXX20-12XXXXXX13-21XXXXXX82-1001</UserId>
      <LogonType>Password</LogonType>
      <RunLevel>LeastPrivilege</RunLevel>
    </Principal>
  </Principals>
  <Settings>
    <MultipleInstancesPolicy>Parallel</MultipleInstancesPolicy>
    <DisallowStartIfOnBatteries>false</DisallowStartIfOnBatteries>
    <StopIfGoingOnBatteries>false</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>PT0S</ExecutionTimeLimit>
    <Priority>7</Priority>
    <RestartOnFailure>
      <Interval>PT2H</Interval>
      <Count>120</Count>
    </RestartOnFailure>
  </Settings>
  <Actions Context="Author">
    <Exec>
      <Command>C:\Windows\System32\WindowsPowerShell\v1.0\powershell.exe</Command>
      <Arguments>"D:\Datenbanken\Datensicherung\myRoboBak\Executables\access.ps1"</Arguments>
      <WorkingDirectory>D:\Datenbanken\Datensicherung\myRoboBak\Executables\</WorkingDirectory>
    </Exec>
  </Actions>
</Task>
Traveler
  • 370

1 Answers1

0

You will need to add the credentials to Credential Manager as the account used to run the scheduled task once, and then it should run fine.

Add this to the top of your script:

Import-Module CredentialManager

New-StoredCredential -Target "webdav.mc.gmx.net" -Username "Username" -Password "Password" -Persist LocalMachine

Save and run the script once as a scheduled task. If successful you can delete the stored New-StoredCredential line and it should work thereafter.