Windows 10 Powershell script to track your laptop

Neemobeer

Windows Forum Team
Staff member
#1
I wrote this basic powershell script. The script tracks your laptop's external IP address, and if it changes it will send you an email with the new external IP and a traceroute. The intended purpose is to help locate your laptop if it is lost or stolen. An ISP would be able to determine who was using the IP.

  • To set it up, you first need to enable your execution policy to allow powershell scripts, this can be done from an elevated powershell prompt Set-ExecutionPolicy -Scope LocalMachine
  • Run the script once manually this will allow you to configure the email settings. The password is stored as a powershell secure string
  • Setup a reoccurring scheduled task as SYSTEM
Code:
$configdir = "$env:ProgramData\Monitor" 
$credfile = "$configdir\cred.txt"
$configfile = "$configdir\config.txt"
$ipfile = "$configdir\ip.txt"

Function Get-ExternalIPAddress
{
    $data = (Invoke-WebRequest -Uri "whatismyip.org" -UseBasicParsing).Content
    ExtractValidIPAddress -String $data
}
Function ExtractValidIPAddress($String)
{
    $IPregex=‘(?<Address>((25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.){3}(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?))’
    If ($String -Match $IPregex) {$Matches.Address}

}

$ip = Get-ExternalIPAddress

#Setup configuration
If (!(Test-Path -Path $configdir))
{
    #Prompt for configuration information
    New-Item -Path $configdir -ItemType Directory
    "Configuration folder missing, please enter setup info..."
    $server = Read-Host -Prompt "Enter email server"
    $port = Read-Host -Prompt "Enter email port"
    $emailto = Read-Host -Prompt "Enter To email address"
    $emailfrom = Read-Host -Prompt "Enter From email address"
    $user = Read-Host -Prompt "Enter email username"
    Write-Host 'Enter your password:' -ForegroundColor Red
    $pass = Read-Host -AsSecureString | ConvertFrom-SecureString | Out-File $credfile
    $ip = Get-ExternalIPAddress

    #Create Configuration File
    $monitor_file = New-Item -Path $configfile -ItemType File
    Out-File -FilePath $monitor_file.FullName -Append -InputObject ("server:$server")
    Out-File -FilePath $monitor_file.FullName -Append -InputObject ("port:$port")
    Out-File -FilePath $monitor_file.FullName -Append -InputObject ("username:$user")
    Out-File -FilePath $monitor_file.FullName -Append -InputObject ("from:$emailto")
    Out-File -FilePath $monitor_file.FullName -Append -InputObject ("from:$emailfrom")

    #Create IP File
    New-Item -Path $ipfile -ItemType File
    Out-File -FilePath $ipfile -InputObject ($ip)
} Else
{
    $server =""
    $port = ""
    $to = ""
    $from = ""
    $user = ""

    #Loop to detect connected network adapters
    #Wait for an adapter to be connected
    $nic = 0
    While( $nic -eq 0 )
    {
        $obj = GWMI -Class Win32_NetworkAdapter -Filter "netconnectionstatus = 2"
        $nic = $obj.Count
    }

    #Compare recorded IP with curent
    #Script will exit if the IP has not changed
    $savedip = Get-Content $ipfile
    $currentip = Get-ExternalIPAddress
    If (($savedip -eq $currentip))
    {
        "External IP has not changed."
        Exit     
    }

    #Read configuration file to configure
    #sending email
    $config = Get-Content $configfile
    Foreach ($c In $config)
    {
        If($c.Contains("server:"))
        {
            $split = $c.Split(":")
            $server = $split[1]
        }
        If($c.Contains("port:"))
        {
            $split = $c.Split(":")
            $port = $split[1]
        }
        If($c.Contains("from:"))
        {
            $split = $c.Split(":")
            $from = $split[1]
        }
        If($c.Contains("to:"))
        {
            $split = $c.Split(":")
            $to = $split[1]
        }
        If($c.Contains("username:"))
        {
            $split = $c.Split(":")
            $user = $split[1]
        }
    }

    #Create Credential object for sending email
    $secpass = Get-Content C:\ProgramData\Monitor\cred.txt | ConvertTo-SecureString
    $PSCred = New-Object -TypeName System.Management.Automation.PSCredential -ArgumentList $user,$secpass

    #Form html message body
    $header = "<!DOCTYPE html>`r<html>`r<head>`r<meta charset=`"UTF-8`"></head>"
    $body += $header
    $body = "<body>`r<p>External IP is now: $ip<br>TraceRoute<br>"
    $trace = tracert 8.8.8.8
    ForEach($t In $trace) { $body += "$t<br>" }
    $body += "</p></body></html>"


    #send email
    Send-MailMessage -SmtpServer $server -Port:$port -From $from -To $to `
     -Subject "External IP has changed" -BodyAsHtml $body -Credential $PSCred -UseSsl
}
 


Last edited:

ussnorway

Windows Forum Team
Staff member
Premium Supporter
#2
Interesting... I assume it runs on the (hypothetical stolen) laptop at boot time?
 


Neemobeer

Windows Forum Team
Staff member
#3
As long as you scheduled the job with the SYSTEM account, then yes.
 


ussnorway

Windows Forum Team
Staff member
Premium Supporter
#4
Well I can confirm the script works although I tried to run it twice before I realized the "need to remove space" was an instruction for me… so it's not muppet/ idiot proof :oops::rolleyes:

I think it should send one email at the first test run just to confirm settings are correct?

P.s at the time of testing my ip address = 121.218.173.246 what's yours
 


Neemobeer

Windows Forum Team
Staff member
#5
Do you know if there is way to disable the emoticons? That's why I had to add the space
 


ussnorway

Windows Forum Team
Staff member
Premium Supporter
#6
Do you know if there is way to disable the emoticons?
Use the insert code option,
Screenshot (393).png

Code:
:p
 


Neemobeer

Windows Forum Team
Staff member
#7
Crap, totally forgot code to update the ip.txt file on change. It's not letting me edit my post...

Need:
Out-File -InputObject $currentip -FilePath $ipfile

After the }
If (($savedip -eq $currentip))
{
"External IP has not changed."
Exit
}
 


This website is not affiliated, owned, or endorsed by Microsoft Corporation. It is a member of the Microsoft Partner Program.