Search This Blog

Tuesday, December 26, 2023

PowerShell: Automating Cheats in Star Wars Knights of the Old Republic

Hello,

This blog post builds a bit on techniques such as sendkey/sendwait, allowing the PowerShell user to automate keystrokes which helps a lot when entering lengthy cheat codes into older games.
As I am using a nordic keyboard layout the way to open the Kotor 2 console is to press shift + backtick.
Keep in mind that you have to edit one of the files in the Steam folder to enable cheats for Knights of the Old Republic 2.

The PowerShell code:

# KOTOR 2 Auto Cheater #

# Sendkey functions #
$Backtick = "+(´)"
$Space = " "
$Enter = "{ENTER}"

<# Cheats hard codes from https://steamcommunity.com/sharedfiles/filedetails/?id=149123471
These variable each contains the actual cheat code of choice, giving you a long list of favorite codes.#>
$treat = "settreatinjury 40"
$compuse = "setcomputeruse 40"
$demo = "setdemolitions 40"
$stealth = "setstealth 40"
$aware = "setawareness 40"
$charm = "setcharisma 40"
$wis = "setwisdom 40"
$int = "setintelligence 40"
$const = "setconstitution 40"
$dex = "setdexterity 40"
$str = "setstrength 40"
$sec = "setsecurity 40"
$rep = "setrepair 40"
$pers = "setpersuade 40"
$exp = "addexp 999999"

# List used in loop, here you simply add variables that you want to include in the loop. #
$listofcheats = $treat, $compuse, $demo, $stealth, $aware, $charm, $wis, $int, $const, $dex, $str, $sec, $rep, $pers, $exp

# This function is responsible for opening the console only. One function, one purpose. #
function Open-Console {
[System.Windows.Forms.SendKeys]::SendWait($Backtick)
[System.Windows.Forms.SendKeys]::SendWait($Space)
}

# This function is responsible for using the cheat that was typed into the Kotor 2 console. #
function Send-Cheat {
[System.Windows.Forms.SendKeys]::SendWait($Enter)
}

<# This is a simple one of function, that accurately lets you reuse a single cheat code without the worry of misspelling #>
function Use-Cheat($code) {
Start-Sleep -Seconds 5;
Open-Console;
[System.Windows.Forms.SendKeys]::SendWait($code);
Send-Cheat;
}

# This is is the automatic function, it runs through the entire list you customize in the script. #
function Use-AllCheats {
    foreach ($cheat in $listofcheats) {
        Start-Sleep -Seconds 5;
        Open-Console;
        [System.Windows.Forms.SendKeys]::SendWait($cheat);
        Send-Cheat;
    }
}

Sunday, December 17, 2023

Windows: Automatic login

Introduction

This post will briefly show how you can set up your Windows device to automatically login upon starting the computer, it works for restarts as well.

It consists of two parts, first part is the GUI way and if that way doesn't work there is registry way.

The necessary security caveat:
Do not add this to a computer that can fall into the hands of the wrong person. It will decrease your device security and it is not encouraged, this post simply illustrates how it can be done.

The GUI way

Start netplwiz from either run or PowerShell.

Right away you will see an option "users must enter a user name and password to use this computer".

Uncheck this, confirm with your password. 

If the option is missing you will have to do the registry way instead.

The registry way

Create a registry file with the following text:

Windows Registry Editor Version 5.00

[HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\PasswordLess\Device\]
"DevicePasswordLessBuildVersion"=dword:00000000

After you have saved it as a .reg-file, you can run it and it will make the necessary changes.
You can probably see the option now in step one if you are curious.

Give the computer a restart and it should now automatically log you into the user.


PowerShell: Create scheduled task

Case where a scheduled task comes in handy

Lately I've been suffering from a explorer process that is not starting upon boot of the computer.

I log in to Windows and the screen is completely black, apart from the mouse pointer sometimes. I've had this issue on a couple of computers over the years, while it is nothing dangerous and easy to fix, it is still annoying.

The quick fix is easy, start task manager using Ctrl + Shift + Escape and run the new task "explorer.exe".

However, I wanted to explore the PowerShell way of perhaps creating a scheduled task that simply checks if the explorer is running, and if not, apply the quick fix automatically. Also I explored whether I could use .bat-file to run a PowerShell script that registers this scheduled task. Unfortunately, for a quick and safe fix it didn't work, you either have to write a more complicated workaround or run the bat file as an admin, which then introduced some other issues. The goal was to keep it very simple.

The PowerShell script that is a failsafe for the explorer process

The code for the fix script looks like this:

function Start-Explorer {

    Start-Process explorer.exe;

}

$Explorer = Get-Process -Name explorer -ErrorAction SilentlyContinue

if (-Not($Explorer)) {

    Start-Explorer;

}

Manually scheduling a task in taskschd.msc

It is completely fine to save this to a .ps1-file and then manually create a scheduled task. Simply start task scheduler, hit "new basic task" once you are in the main folder of tasks.

Trigger:
Being logging in.

Action:
Start a program.

Program/script:
powershell.exe

The added arguments:
-windowstyle hidden -executionpolicy bypass -scope currentuser "C:\temp\PathToScript.ps1"

Basically this tells the computer that upon login (by the user creating the task), run the specified script while bypassing execution policy and only for the user, this time.

Scheduling a task using PowerShell, the basics

This is the very basic method of a PowerShell script that is intended to register a task in the task scheduler. When I tried dot sourcing it, it failed to bypass the execution policy and when I dot sourced it as an admin it created a scheduled task for all users of the computer. This could probably be altered with more detailed parameters and a permanent fix of the execution policy, but it is beside the point of this post. The point of this segment is to show the basic mechanics of using PowerShell to schedule a task.

$action = New-ScheduledTaskAction -Execute "powershell.exe" -Argument "-executionpolicy bypass -file `\"C:\Temp\Sample.ps1`\""
$trigger = New-ScheduledTaskTrigger -AtLogon
$task = New-ScheduledTask -Action $action -Trigger $trigger
Register-ScheduledTask NameOfTask -InputObject $task

As you can see it is a quite interesting and straightforward mechanic.

  1. The very first step is that you tell the computer what to do, in this case run a script with a few parameters, the extra symbols in the file path helps to character escape the extra quotes.
  2. Secondly you tell the computer when to do it, the trigger, in this case upon logging in.
  3. Third you combine the what and when into a task variable.
  4. Lastly you register this task, giving it a name and supplying the task variable to the cmdlet.
When working with PowerShell and the task scheduler, you can of course supply much more details, for example which user should be affected. However, from what I could see you are required to run this script as an admin if you want to run it from the console (dot sourcing).

Creating a .bat-file that runs a PowerShell script

As an added bonus and to wrap up the post of today, I will show you a simple way to use a bat file to kickstart a .ps1-file, with supplied parameters like execution policy bypass.

Open notepad, create a file with the following command:

powershell.exe -ExecutionPolicy Bypass -File .\ScriptInSameDirectory.ps1

You can add parameters like 
-nologo 
-windowstyle hidden 
-executionpolicy bypass and to specify current user add -scope currentuser

Note that if the .bat-file is not in the same folder as the target .ps1 you need to specify full path.

Good luck!

Thursday, December 7, 2023

Review: Alogic MX3 Docking station

A while back ago I got an Alogic MX3, it is a docking station with 3 displayports that I use to connect both my work computer and personal computer.

They are both connected using a USB-C cable to the dock, so when my work day is complete I can connect my personal computer instead.

So far I am rather okay with it, but I've noticed some unfortunate characteristics.

It is too underpowered to reliably power my Surface Pro 7, my Surface Dock 2 does not have that issues. The symptom is that the Alogic MX3 dock does show content on all three monitors but it doesn't charge the battery. Peripherals does not seem to be affected. 

When switching from my work computer to my personal computer it sometimes does not activate my third monitor as well.

The solution to the power issue is to turn the dock off for a few seconds and then turn it on again, that way it seems to start charging the computer again. As for the monitor issue it is simply a matter of extending the screen again to the third monitor.

The over all impression is that the dock looks good, has the right ports for my needs, is easy to work with but I would not recommend a purchase due to the quality of life issues I am experiencing.

Sunday, November 26, 2023

Cryptography: Enciphering with PowerShell

The idea came to me after having followed some ARG's (alternate reality games), where people solve puzzles, often decoding some enciphered texts using more or lesser known cipher techniques, such as the classic Caesar Cipher, where you shift a letter in the alphabet a number of steps.

I wanted to see if I could create a script in PowerShell that would perform this action, after prompting ChatGPT a bit I managed to get the main logic behind the shifting.

This was put into an encoding function and a decoding function. Later on after the script matured, I decided to create a basic GUI for it, based off of the simple password generator I had created earlier.

This version offers you case cleaing, optional clipboard copy and decoding/encoding. In the future there might be some error handling put into the code, such as handling empty text fields.




This is what the code looks like:

# Caesar cipher /w GUI #


[void] [System.Reflection.Assembly]::LoadWithPartialName("System.Windows.Forms")


$Main = New-Object System.Windows.Forms.Form

$Main.text = "Caesar Cipher 1.1"

$Main.size = New-Object system.drawing.size(600,200)

$Main.BackColor = "DarkGray"

$Main.FormBorderStyle = "FixedDialog"


$PlainText = New-Object System.Windows.Forms.TextBox

$PlainText.Size = New-Object System.Drawing.Size(400,100)

$PlainText.Location = New-Object System.Drawing.Size(50,30)

$PlainText.BackColor = "Black"

$PlainText.ForeColor = "LightGreen"

$Main.Controls.Add($PlainText)


$CipherText = New-Object System.Windows.Forms.TextBox

$CipherText.Size = New-Object System.Drawing.Size(400,100)

$CipherText.Location = New-Object System.Drawing.Size(50,50)

$CipherText.BackColor = "Black"

$CipherText.ForeColor = "LightGreen"

$Main.Controls.Add($CipherText)


$Clipboard = New-Object System.Windows.Forms.CheckBox

$Clipboard.Size = New-Object System.Drawing.Size(80,40)

$Clipboard.Location = New-Object System.Drawing.Size(50,75)

$Clipboard.Checked = $False

$Clipboard.Text = "Clipboard"

$Main.Controls.Add($Clipboard)


$CipherKey = New-Object System.Windows.Forms.TextBox

$CipherKey.Size = New-Object System.Drawing.Size(30,50)

$CipherKey.Location = New-Object System.Drawing.Size(140,87)

$CipherKey.Text = "1"

$Main.Controls.Add($CipherKey)


function Encode-CaesarCipher {

    param ($pt, $ck)

    $pt = $PlainText.Text;

    $ck = $CipherKey.Text;

    $e = ""

    foreach ($c in $pt.ToUpper().ToCharArray()) {

        $x = [int][char]$c

        if ($x -ge 65 -and $x -le 90) { $e += [char](65 + (($x - 65 + $ck) % 26)) }

        elseif ($x -ge 97 -and $x -le 122) { $e += [char](97 + (($x - 97 + $ck) % 26)) }

        else { $e += $c }

    }

    $CipherText.text = $e

    if ($Clipboard.checked) {$e | Set-Clipboard}

}


function Decode-CaesarCipher {

    param ($ct, $ck)

    $ct = $CipherText.Text;

    $ck = $CipherKey.Text;

    $m = ""

    foreach ($c in $ct.ToUpper().ToCharArray()) {

        $x = [int][char]$c

        if ($x -ge 65 -and $x -le 90) { $m += [char](65 + (($x - 65 - $ck + 26) % 26)) }

        elseif ($x -ge 97 -and $x -le 122) { $m += [char](97 + (($x - 97 - $ck + 26) % 26)) }

        else { $m += $c }

    }

    $PlainText.text = $m

    if ($Clipboard.checked) {$m | Set-Clipboard}

}


$EncodeButton = New-Object System.Windows.Forms.Button

$EncodeButton.Size = New-Object System.Drawing.Size(60,40)

$EncodeButton.Location = New-Object System.Drawing.Size(180,87)

$EncodeButton.Text = "Encode"

$EncodeButton.BackColor = "Green"

$EncodeButton.ForeColor = "Yellow"

$EncodeButton.Add_Click({Encode-CaesarCipher;})

$Main.Controls.Add($EncodeButton)


$DecodeButton = New-Object System.Windows.Forms.Button

$DecodeButton.Size = New-Object System.Drawing.Size(60,40)

$DecodeButton.Location = New-Object System.Drawing.Size(250,87)

$DecodeButton.Text = "Decode"

$DecodeButton.BackColor = "Green"

$DecodeButton.ForeColor = "Yellow"

$DecodeButton.Add_Click({Decode-CaesarCipher;})

$Main.Controls.Add($DecodeButton)


[void] $Main.ShowDialog()

Friday, October 6, 2023

Keyboard: Remapping function keys

Looking at my keyboard I was wondering if there was a way for me to change the built in functions of the keyboard such as "open default mail app" or "play/pause music".

Seems like there is a way by editing the registry.

The following way will change the settings for all users of the computer, and as always, the registry is a dangerous place to edit if you aren't careful.

1. Open regedit as administrator and go to the following adress:  HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Explorer\AppKey\

2. You will see numbered folders (called "keys"). Folder number 16 is your media player, in my case it was preset to open Windows Media Player. Thus a good candidate to be replaced.

3. Within the folder of your choice create a string value (REG_SZ) called ShellExecute.
Open that file up and set its value to a path leading to your program, put within quotation marks.
In my case I chose the path to PowerShell: "C:\Program Files\PowerShell\7\pwsh.exe"


In my case the effect was immediate, no restart was required. However, the day after it was not working as intended. It seemed to be working only if I had an admin session of regedit open. Trying to add it to Current User hive did not seem to work either.

We know that folder number 16 equated to the media button. What other buttons might there be?
Well this article lists all the potential numbers, obviously your keyboard might not have the email button and you might not be able to remap the email button to another program. I only chose to inspect/modify the already existing registry keys (15, 16, 17, 18, 7) instead of creating new ones.

Based of the article we can see the following examples of registry keys and their inherent functions:

1 = Browser navigation backward, 2 = forward, 3 = refresh, 4 = stop, 5 = search, 6 = favorites, 7 = home.

8 = mute volume, 9 = volume down, 10 = volume up, 11 = next track, 12 = previous track, 13 = stop, 14 = play/pause

15 = mail, 16 = media, 17 = app 1, 18 = app 2, 19 = bass down, 20 = bass boost, 21 = bass up, 22 = treble down, 23 = treble up

The numbers are arbitrary, you have to look where the functions are located physically on your keyboard. In my case the number 16 (media) was located on fn + escape. Thus, when I pressed fn + escape it started my PowerShell window. Beware, it seems to be unstable and might stop working for you though.

Here is the reg file content that you can work with, as you can see I experimented with Current User.

Windows Registry Editor Version 5.00

[HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Explorer\AppKey\16]
"ShellExecute"="C:\\Program Files\\PowerShell\\7\\pwsh.exe"

Enjoy!

Tuesday, September 19, 2023

Maintenance: Updating your Surface Pro 7

In my job I have been updating a few docking stations with fresh firmware. Personally I find it to be a nice little routine to keep the firmware and software up to date, like putting things to order.

For example there is firmware for both Lenovo and Dell docking stations, and keeping that in mind I was looking for a way to update the firmware for my Surface Dock 2.

Updating your Surface Dock 2:
The easy way is to use the Surface app, downloadable from the Microsoft Store.
After installing it and opening it, you get an easy to use menu. You can interact with your dock, mouse and pen for example.


By clicking clicking on the dock you can make sure that your firmware is up to date. There you can also turn different ports on and off.

For someone that would need a manual update, it seems like Microsoft offers a few versions as well, based on your device.

Updating your Surface Pro 7 drivers:
You can also update the driver kit with a roughly 600 mb sized file with all the drivers. 
To download it go here.

Running a diagnostic toolkit to identify errors:
You might also want to grab the Surface Diagnostic Toolkit, it let's you test the functionality of your device, a great tool for singling out various issues that you might have with your computer.
To get the toolkit, go to this link.

Now you have been provided with some simple and easy to access tools to service your device.

Sunday, September 17, 2023

Hardware: Finding device info using PowerShell

The hunt for more information began with a new keyboard I have. A wireless keyboard called "Deltaco TB-632". As an avid Deltaco fan I also knew that they rarely make their own products, but they rebrand devices that they source from other companies.

One example is their smart home devices that in at least one case seems to come from China.

So how did I go about finding more information about this keyboard? Well, old trusty PowerShell of course. After first trying to find a way using the control panel and settings to see a MAC address or other identifying information I simply turned to the command Get-Pnpdevice.

If you run this command you will discover practically all devices that has been connected to the computer since the last OS installation. They will be listed as Unknown if they aren't connected and OK if they are working fine.

This is the main code I ran: get-pnpdevice -Class USB | Select-Object status, friendlyname, instanceid | Sort-Object -Property friendlyname

First I ran the command without the USB wireless receiver attached.

Then I attached the receiver and ran the command again. By doing this I could see which device that turned from Unknown to OK.

In this specific case I got a result looking like this:

OK USB Composite Device USB\VID_248A&PID_8367\5&194485C0&0&1

Now that you have the VID (vendor ID) and PID (device ID) for your device you can simply Google these identifiers.

My result indicated that the Deltaco TB-632 seems to be provided by the company Maxxter and the USB device is called Telink Wireless Receiver.

Using the same method I tried looking for the keyboard unit itself as well in the list of PnP devices. I tested this theory by running the following command without and with the device plugged in.

(get-pnpdevice -Status OK).Count



The result was that 8 devices appeared when the receiver was plugged in.

To find out which devices that make up the difference you can combine Get-Pnpdevice with Compare-Object. Adapt the code after your individual situation.

First run this code with the device in:
 get-pnpdevice -Status OK | Sort-Object ClassGuid | Out-file -FilePath C:\temp\dev1.txt

Then run this code with the device out:
get-pnpdevice -Status OK | Sort-Object ClassGuid | Out-file -FilePath C:\temp\dev2.txt

To then compare the output run this comand:

Compare-Object -ReferenceObject (Get-content -path C:\temp\dev1.txt) -DifferenceObject (Get-Content -Path C:\temp\dev2.txt)

The output will look like this, the arrow shows that the result is present in the reference object, which in this case was to the left and missing in the difference object to the right, which means that they disappeared when we unplugged the device.


From here you can then investigate further from the VID and PID that you get.

Happy hunting :-)


Wednesday, August 30, 2023

Domain: Purchasing a new one

When I first started this blog I had to get a domain name in order to attach a more personal URL to my blog.

As time went by I realized I wanted a .se domain but it was already taken.

If you find yourself in the same situation you can go to who.is and search for the domain you want.

Here you will see how long it has existed for, when it is bound to expire and most importantly when you can buy it.

The release date is also the day when you can purchase it on, I contacted the current host just in case but they could not provide me with much more information than what is already public.

Next I went to the organisation that is responsible for the .se top domain. Here I received information about which hour it is released. In my case very early in the morning (even with the summer time).

Now it was just a matter of waiting until the right time, I tested two hosting providers but they were not synced. Finally I found a Swedish provider where I could buy the domain with no issues.

So my advice is: do your research, set your calendar and alarm, and make sure your credit card is working.

Saturday, July 1, 2023

CMD: Access files without logging in

If you are locked out of your computer and you still want to access the system you can follow these steps.

Most likely you will be locked out from C: drive where your personal data might be stored due to Bitlocker, but this is how you can browse around and find out.

Shift click on restart, go to troubleshooting and advanced tools. Choose the command prompt.

Now you have an administrative prompt starting in the X: drive, here are a few things you can explore.

  • Run wmic logicaldisk get name to find out what drives there are, you can even access a connected USB drive this way. Take note of the name if you want to use it.

  • You can explore other drives by running cd /d d: for example, where d: is the other drive, in this example the USB that I connected.

  • Use the command dir to list all the directories and files in your current folder. Use cd to get the name of your current location.

  • You can navigate by supplying the full path, or the next directory.
    Example: cd d:\folder\folder2

  • To go back up one level use the command cd .. 

  • In this administrative prompt you are actually running an instance of Windows PE, a light-weight OS, also known as Windows Preinstallation Environment. It has limited functionality.
    You can still use the command prompt to start basic programs such as taskmgr, notepad and regedit.

    You can use notepad to edit and save scripts on your USB. First navigate to the right directory, then pick the program and file as shown below.

    Example: notepad myscript.bat

    From task manager you can trigger "run" as well, but executables such as powershell.exe are not available. Nor can you bring a copy of Powershell with you on the USB.

  • You can run batch files, .bat, from your USB. Just navigate to the directory and write the name of the script.

    This is an example of how you can extract data from the registry and save it to your USB using a batch file. Put this code in a text file and save it as a .bat file.

    Make sure that you replace D:\ with whatever drive your USB is.
@echo off
    setlocal
        cd /d D:\
          echo %cd%

              :PROMPT
                SET /P RUSURE=Are you sure (Y/N)?
                  IF /I "%RUSURE%" EQU "N" GOTO END
                    IF /I "%RUSURE%" EQU "Y" GOTO PAYLOAD

                        :PAYLOAD
                          reg save hklm\sam ./sam.save /y
                            reg save hklm\system ./system.save /y

                                :END
                                  endlocal

                                  • Finally, to clear text use cls and to exit the prompt window use exit, which will return your to the recovery environment. From there you can return to the normal OS.