Batch Example via WinRPC

Parsing the piped input

As mentioned above, a BASE64 string will be piped into your script, which includes the username and new password (among other data), which you will use to rotate the Windows Scheduled Task credentials.

Using the below snippet, we can take the piped input and use certutil to decode the BASE64 string. These will be saved to temporary files and cleaned up later, as is the custom in bat scripts, as certutil only accepts files as input.

@echo off
for /f "tokens=*" %%a in ('more') do set input=%%a

set base64tmp=%temp%\base64.tmp
set json=%temp%\json.tmp

echo %input% > %base64tmp%
certutil -decode %base64tmp% %json%

jq can be used on the resulting JSON file to get the values of user and newPassword.

for /f "usebackq delims=" %%a in (`jq -r .user %json%`) do set "user=%%a"
for /f "usebackq delims=" %%a in (`jq -r .newPassword %json%`) do set "newPassword=%%a"

Using Admin Credentials

To update the 'Log On As' property on a Windows Scheduled Task, you will need a credential with the appropriate permissions, such as an Administrator account.

When attaching a PAM script to a record, you have the option to add a Resource Credential that is passed to the Gateway as part of the BASE64-encoded JSON data. The above credential will need to be attached as a Resource Credential.

As many Resource Credentials can be attached to a PAM script, knowing the UID of the Resource Credential you have attached helps ensure your script uses the correct one to update the Service's 'Log On As' property.

We can use jq to access the attached Resource Credential and filter by the records UID.

set adminrecord=%temp%\adminrecord.tmp
set adminuid=<Admin UID>
jq -r ".[] | select(.uid == \"%adminuid%\")" %recordsjson% > %adminrecord%

@REM pull the login, domainName, and password from the %adminrecord% JSON object
for /f "usebackq delims=" %%a in (`jq -r .login %adminrecord%`) do set "adminuser=%%a"
for /f "usebackq delims=" %%a in (`jq -r .domainName %adminrecord%`) do set "domainname=%%a"
for /f "usebackq delims=" %%a in (`jq -r .password %adminrecord%`) do set "adminpassword=%%a"

@REM Create the admin usermain by combining the username@domainname
set adminusername=%adminuser%@%domainname%

Updating the Scheduled Task

The schtasks command is used to update the desired Scheduled Task using the values you just extracted. In addition to the new credentials, you will need the Admin credentials from above.

schtasks /change /tn "<Task Name>" /s "<Target Server>" /u %adminusername% /p %adminpassword /ru %user% /rp %newPassword%

Full Example

@echo off
for /f "tokens=*" %%a in ('more') do set input=%%a

set base64tmp=%temp%\base64.tmp
set json=%temp%\json.tmp
set recordsb64=%temp%\recordsb64.tmp
set recordsjson=%temp%\records.tmp

echo %input% > %base64tmp%
certutil -decode %base64tmp% %json%

for /f "usebackq delims=" %%a in (`jq -r .user %json%`) do set "user=%%a"
for /f "usebackq delims=" %%a in (`jq -r .newPassword %json%`) do set "newPassword=%%a"
for /f "usebackq delims=" %%a in (`jq -r .records %json%`) do set "records=%%a"

echo %records% > %recordsb64%
certutil -decode %recordsb64% %recordsjson%

@REM Find the admin record that has a uid that matches %adminuid% and save to %adminrecord%
set adminrecord=%temp%\adminrecord.tmp
set adminuid=<Admin UID>
jq -r ".[] | select(.uid == \"%adminuid%\")" %recordsjson% > %adminrecord%

@REM pull the login, domainName, and password from the %adminrecord% JSON object
for /f "usebackq delims=" %%a in (`jq -r .login %adminrecord%`) do set "adminuser=%%a"
for /f "usebackq delims=" %%a in (`jq -r .domainName %adminrecord%`) do set "domainname=%%a"
for /f "usebackq delims=" %%a in (`jq -r .password %adminrecord%`) do set "adminpassword=%%a"

@REM Create the admin usermain by combining the username@domainname
set adminusername=%adminuser%@%domainname%

del %base64tmp%
del %json%
del %recordsb64%
del %recordsjson%
del %adminrecord%

@REM Update the scheduled task with the new password
schtasks /change /tn "<Task Name>" /s "<Taget Server>" /u %adminusername% /p %adminpassword% /ru %user% /rp "%newPassword%"
if %errorlevel% neq 0 exit /b %errorlevel%

Last updated