I've seen multiple posts on twitter recently where people showed how to retrieve data from a company device.
The Retire My PC app (shown below)
helps to add a stronger layer of protection to your corporate devices by deleting the Bitlocker recovery information from the TPM, before shutting down the computer, and it gives your users a Self-Service way of securing company data on old computers before handing them back. In case you haven't seen that blog post already, please familiarize yourself with the Retire My PC solution here.
In this blog post I'll show you how you can verify that the user has retired their old device by running a script on their new device.
Step 1. Add a new httptrigger
In the Resource Group that you created in Step 1 of the first blog post, create a new httptrigger and paste in the following code.
#######################################################################################################################################
# use this code in a http trigger as part of a function app
# for more details see ...
# Niall Brady,2021/10/05
#######################################################################################################################################
using namespace System.Net
# Input bindings are passed in via param block.
param($Request, $TriggerMetadata, $inputTable)
$Tenant = "windowsnoob.com"
$triggerName = "Check if user retired PC previously"
# Write to the Azure Functions log stream.
Write-Host "PowerShell HTTP trigger function processed a request."
# Interact with query parameters or the body of the request.
$CheckUser = $Request.Query.CheckUser
if (-not $CheckUser) {
$CheckUser = $Request.Body.CheckUser
}
$a = Get-Date
$body = $body + "$a ------------------------------------`n"
$a = Get-Date
$body = $body + "$a Starting the following trigger: '$triggerName'.`n"
$a = Get-Date
$body = $body + "$a Connected to tenant: '$Tenant'.`n"
if ($CheckUser) {
$a = Get-Date
$body = $body + "$a Looking for the following user name: '$CheckUser'.`n"
#}
#Put all table rows into $table
#$found=""
$table = [System.Collections.ArrayList]::new();
foreach($row in $inputTable){
#validate section
# look for any rows where the user we are checking equals the UserName column...
if ($CheckUser -EQ $row.UserName -and $($row.DateRetired) -gt $(Get-Date).AddDays(-14)) {
$table.Add(@{
sUserName = $row.UserName;
dateRetired = $row.DateRetired;
sStatus = $row.Status;
sComputerName = $row.ComputerName;
})
#$found+="$($table[$table.Count-1].sComputerName) - $($table[$table.Count-1].sUserName) - $($table[$table.Count-1].sStatus) - $($table[$table.Count-1].dateRetired)"
$found+="$($table[$table.Count-1].sComputerName) - $($table[$table.Count-1].dateRetired)"
$body = $body + "$a FOUND record: '" + $found + "'.`n"
}
else
{}
# {$body = $body + "Did not find a matching record`n"}
}
}
$a = get-date
$body = $body + "$a Exiting Azure function.`n"
$a = Get-Date
$body = $body + "$a ------------------------------------`n"
# show the output to the browser...Associate values to output bindings by calling 'Push-OutputBinding'.
Push-OutputBinding -Name Response -Value ([HttpResponseContext]@{
StatusCode = [HttpStatusCode]::OK
Body = $body
})
Step 2. Integrate the trigger with Azure tables
In the newly created trigger click save and then click on Integration. You will be adding integration with the Azure tables created in the first blog post with the new trigger for both the input and output (marked in yellow below).
For Inputs, click on + Add input then... configure the following settings:
For Binding Type, select: Azure Table Storage
For Storage Account Connection, select: RetireMyPC_setting
For Tablename enter: devicestatus
as shown below in yellow.
Click OK when done.
You should see it looking like this.
Next, for Output table click on + Add Output and fill it in like so....
For Binding Type, select: Azure Table Storage
For Storage Account Connection, select: RetireMyPC_setting
For Tablename enter: devicestatus
like this.
Click OK when done, your httptrigger is now integrated with Azure tables.
Step 3. Get the scripts
Download the following files and extract somewhere useful.
Note: you will need to login to windows-noob.com to download the scripts.
You'll need the ServiceUI.exe executable file to display user interfaces (UI) to end users when operating in SYSTEM context. To get the file, download and install MDT somewhere and navigate to C:\Program Files\Microsoft Deployment Toolkit\Templates\Distribution\Tools\x64. To download MDT click here.
Copy the ServiceUI.exe file to your extracted Encode Files folder
Copy the IntuneWinAppUtil.exe file to the root of your extracted scripts folder
Step 5. Modify the scripts
Modify the following script: win.ap.retiremypc_verification.ps1
get the funtion URL of the new httptrigger you created in step 1 by looking at this graphic
paste that function URL into line 72
next edit line 145 to your preferences
ok, now move on to script CreateScheduledTask_win.ap.retiremypc.verification.ps1
and edit line 41
next fill in the values of the encoded files into lines 53-56
so for example, here is before
and after...
if you don't know how to encode the files look at the encode.ps1 script and you'll figure it out, long story short, modify the path, then run the script, it'll generate 4 txt files and you need to use the contents of those txt files in these variables, note that you need to encode these files every time you make a change to their contents and then paste in the new txt for each file into the main script.
Step 6. Create the intunewin package
Browse to the folder containing your files and run the IntuneWinAppUtil.exe.
Step 7. deploy a Win32 app
Next you'll deploy the new package to your selected users.
In Microsoft Endpoint Manager click on the Apps icon, select All apps, select +Add and then select Windows App 32
Point it to the win32app_target folder and select the previously created .intunewin file
configure the app like so..
On the App information screen,enter the name etc...
on the Program screen enter the following install command install_CreateScheduledTask_RetireMyPC_verification.cmd and set the install behaviour to System
on the requirements
and on the detection rules...
..
lastly deploy it to your Windows Autopilot users azure ad group and the rest will take care of itself.
Step 8. Verify the end result
On a newly deployed Windows Autopilot machine, login and check the scheduled tasks folder, in there you should see your targeted user has a new scheduled task, this task is scheduled to run daily for a month starting 14 days after Windows Autopilot completes enrollment.
You can wait 14 days or just run it by right clicking and choose Run.
If the task detects that the user retired a pc in the last x days then the task will run and self-delete, and the user will not see any message, however, if the logged on user has no record of a computer in Azure tables in the last 14 days then the following message will appear
This popup message will appear daily for the next 2 weeks (you can configure that via the scheduled task script), and can be 'fixed' by the end user either retiring their old pc OR via a help desk manually entering the details.
That's it for this blog post, until the next one, adios !
Introduction
I've seen multiple posts on twitter recently where people showed how to retrieve data from a company device.
The Retire My PC app (shown below)
helps to add a stronger layer of protection to your corporate devices by deleting the Bitlocker recovery information from the TPM, before shutting down the computer, and it gives your users a Self-Service way of securing company data on old computers before handing them back. In case you haven't seen that blog post already, please familiarize yourself with the Retire My PC solution here.
In this blog post I'll show you how you can verify that the user has retired their old device by running a script on their new device.
Step 1. Add a new httptrigger
In the Resource Group that you created in Step 1 of the first blog post, create a new httptrigger and paste in the following code.
####################################################################################################################################### # use this code in a http trigger as part of a function app # for more details see ... # Niall Brady,2021/10/05 ####################################################################################################################################### using namespace System.Net # Input bindings are passed in via param block. param($Request, $TriggerMetadata, $inputTable) $Tenant = "windowsnoob.com" $triggerName = "Check if user retired PC previously" # Write to the Azure Functions log stream. Write-Host "PowerShell HTTP trigger function processed a request." # Interact with query parameters or the body of the request. $CheckUser = $Request.Query.CheckUser if (-not $CheckUser) { $CheckUser = $Request.Body.CheckUser } $a = Get-Date $body = $body + "$a ------------------------------------`n" $a = Get-Date $body = $body + "$a Starting the following trigger: '$triggerName'.`n" $a = Get-Date $body = $body + "$a Connected to tenant: '$Tenant'.`n" if ($CheckUser) { $a = Get-Date $body = $body + "$a Looking for the following user name: '$CheckUser'.`n" #} #Put all table rows into $table #$found="" $table = [System.Collections.ArrayList]::new(); foreach($row in $inputTable){ #validate section # look for any rows where the user we are checking equals the UserName column... if ($CheckUser -EQ $row.UserName -and $($row.DateRetired) -gt $(Get-Date).AddDays(-14)) { $table.Add(@{ sUserName = $row.UserName; dateRetired = $row.DateRetired; sStatus = $row.Status; sComputerName = $row.ComputerName; }) #$found+="$($table[$table.Count-1].sComputerName) - $($table[$table.Count-1].sUserName) - $($table[$table.Count-1].sStatus) - $($table[$table.Count-1].dateRetired)" $found+="$($table[$table.Count-1].sComputerName) - $($table[$table.Count-1].dateRetired)" $body = $body + "$a FOUND record: '" + $found + "'.`n" } else {} # {$body = $body + "Did not find a matching record`n"} } } $a = get-date $body = $body + "$a Exiting Azure function.`n" $a = Get-Date $body = $body + "$a ------------------------------------`n" # show the output to the browser...Associate values to output bindings by calling 'Push-OutputBinding'. Push-OutputBinding -Name Response -Value ([HttpResponseContext]@{ StatusCode = [HttpStatusCode]::OK Body = $body })
Step 2. Integrate the trigger with Azure tables
In the newly created trigger click save and then click on Integration. You will be adding integration with the Azure tables created in the first blog post with the new trigger for both the input and output (marked in yellow below).
For Inputs, click on + Add input then... configure the following settings:
as shown below in yellow.
Click OK when done.
You should see it looking like this.
Next, for Output table click on + Add Output and fill it in like so....
like this.
Click OK when done, your httptrigger is now integrated with Azure tables.
Step 3. Get the scripts
Download the following files and extract somewhere useful.
Note: you will need to login to windows-noob.com to download the scripts.
Encode files.zip
Step 4. Get ServiceUI.exe from MDT
You'll need the ServiceUI.exe executable file to display user interfaces (UI) to end users when operating in SYSTEM context. To get the file, download and install MDT somewhere and navigate to C:\Program Files\Microsoft Deployment Toolkit\Templates\Distribution\Tools\x64. To download MDT click here.
Copy the ServiceUI.exe file to your extracted Encode Files folder
Step 5. Get the Win32 content prep tool
Download the Win32 content prep tool from here.
Copy the IntuneWinAppUtil.exe file to the root of your extracted scripts folder
Step 5. Modify the scripts
Modify the following script: win.ap.retiremypc_verification.ps1
get the funtion URL of the new httptrigger you created in step 1 by looking at this graphic
paste that function URL into line 72
next edit line 145 to your preferences
ok, now move on to script CreateScheduledTask_win.ap.retiremypc.verification.ps1
and edit line 41
next fill in the values of the encoded files into lines 53-56
so for example, here is before
and after...
if you don't know how to encode the files look at the encode.ps1 script and you'll figure it out, long story short, modify the path, then run the script, it'll generate 4 txt files and you need to use the contents of those txt files in these variables, note that you need to encode these files every time you make a change to their contents and then paste in the new txt for each file into the main script.
Step 6. Create the intunewin package
Browse to the folder containing your files and run the IntuneWinAppUtil.exe.
Step 7. deploy a Win32 app
Next you'll deploy the new package to your selected users.
In Microsoft Endpoint Manager click on the Apps icon, select All apps, select + Add and then select Windows App 32
Point it to the win32app_target folder and select the previously created .intunewin file
configure the app like so..
On the App information screen, enter the name etc...
on the Program screen enter the following install command install_CreateScheduledTask_RetireMyPC_verification.cmd and set the install behaviour to System
on the requirements
and on the detection rules...
lastly deploy it to your Windows Autopilot users azure ad group and the rest will take care of itself.
Step 8. Verify the end result
On a newly deployed Windows Autopilot machine, login and check the scheduled tasks folder, in there you should see your targeted user has a new scheduled task, this task is scheduled to run daily for a month starting 14 days after Windows Autopilot completes enrollment.
You can wait 14 days or just run it by right clicking and choose Run.
If the task detects that the user retired a pc in the last x days then the task will run and self-delete, and the user will not see any message, however, if the logged on user has no record of a computer in Azure tables in the last 14 days then the following message will appear
This popup message will appear daily for the next 2 weeks (you can configure that via the scheduled task script), and can be 'fixed' by the end user either retiring their old pc OR via a help desk manually entering the details.
That's it for this blog post, until the next one, adios !
Share this post
Link to post
Share on other sites