All posts by Fawcs

The author is working as an IT-Systems Engineer for an Austrian company and has spezialiced on Linux (RHEL), Deployment and Monitoring but is also working with VMware, Windows, Cisco, ...

Nerdfonts in zsh for exa

After switching to exa as an ls-replacement i also wanted to make use of the nerd-font support ho have icons displayed for files.

alias etree='exa --color --tree --icons=always'

However, in reality the fonts never looked the same in my terminal as in the web preview

So, to easy things up (getting the zip, unzipping it in ~/.local/share/fonts and updateing the fonts-cache) there is a little function which can be placed in the .zshrc/.bashrc to automate things.

#Function to install NerdFonts
function install_nerdfont()
{
	if [ -not $1 ];
	then	
		echo -e "\e[91mParameter missing!\e[0m"
	fi

	cd ~/.local/share/fonts
	wget $1
	unzip -u *.zip
	rm *.zip
	fc-cache -fv	
	cd -

}

Once executed with the download-URL as a paremeter, the font will be installed to your home directory.

If the fonts should be installed system-wide, this can be archived by placing them in /usr/local/share/fonts (folder might needs to be created if it does not exist).

Once the fonts are installed – the terminal-profile must be configured to use the newly installed fonts and that’s it.

Running into “The parameter is incorrect.” / “HRESULT 0x80070057” when managing scheduled tasks via powershell

It took me quite some troubleshooting time, but in the end it’s a quite interessting conclusion.

After trying to create a scheduled task that runs every second Saturday per month, I ran into the following error:

Set-ScheduledTask : The parameter is incorrect.
At C:\ITX\itxWindowsUpdate.ps1:436 char:5
+     Set-ScheduledTask -InputObject $task -User $(Get-LocalUser -Name  ...
+     ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    + CategoryInfo          : InvalidArgument: (PS_ScheduledTask:Root/Microsoft/...S_ScheduledTask) [Set-ScheduledTask], CimException
    + FullyQualifiedErrorId : HRESULT 0x80070057,Set-ScheduledTask

As Windows Powershell is not able to create monthly tasks I used schtasks.exe utility to create the skeleton for the task/minimal task containing the trigger-definition and afterwards manipulate it via powershell to add the missing configuration.

To do so i used Get-ScheduledTask to obtaint he object references for the task and Set-ScheduledTask to write the object again.

Turns out – the task obtained via Get-ScheduledTask contains the trigger defintion for the montly repetition which can’t be handled by powershell and therefor the task itself can not be saved again but results in the above error. 😜

As it seems there are only two ways on how to deal with that problem:
Export the task-definition as an XML and just reimport it via powershell on other systems which require the same configuration (currently untested) or run it daily and deal with the problem within the script.

Lil bit of the debugging-code as a reference for future projects.

Write-Host -ForegroundColor Yellow "Modifying the task"
$action=New-ScheduledTaskAction -Execute "C:\Windows\System32\WindowsPowerShell\v1.0\powershell.exe" -Argument '-NoProfile -command "& C:\BLUB\WindowsUpdate\WindowsUpdate.ps1 -reboot_machine 0"'
$principal = New-ScheduledTaskPrincipal -LogonType Password -RunLevel Highest -UserId "$($env:COMPUTERNAME)\Administrator"
#$principal = New-ScheduledTaskPrincipal -RunLevel Highest -UserId "$($env:COMPUTERNAME)\Administrator"

#$task=New-ScheduledTask -Action $action -Description "Daily Update Task for Monitoring and Defender Updates" -Trigger $trigger -Settings $settings -Principal $

$task=$(Get-ScheduledTask -TaskName $task_name -TaskPath \BLUB\)
#$task.Actions=$action
$task.Description="TEST_test"
#$task.Principal=$principal
#Register-ScheduledTask -TaskName $task_name -InputObject $task -TaskPath BLUB -User $(Get-LocalUser -Name Administrator) -Password $password
$task | Set-ScheduledTask -User $(Get-LocalUser -Name Administrator) -Password $password
#-User $(Get-LocalUser -Name Administrator) -Password $password 
#Set-ScheduledTask -TaskPath "BLUB" -TaskName $task_name -Action $action -Principal $principal
#-Principal $principal
# -User $(Get-LocalUser -Name Administrator) 

Customizing powershell prompt

After enabling OpenSSH on Windows I had the issue that powershell sessions could be mixed up quite easily as it does not display which host is opened in which session.

to work around that a custom prompt function can be specified in the powershell profile

powershell profile is loaded on startup of a powershell window. By default there is no file but it can be created. The file itself is referenced by the PS env $PROFILE.

PS C:\Users\usr> $PROFILE
C:\Users\usr\Documents\WindowsPowerShell\Microsoft.PowerShell_profile.ps1

To change the default prompt (PS C:\User\usr>) the file can be edited and a prompt function can be added:

function prompt{
	"$("[$([System.Environment]::UserName)@$([System.Environment]::MachineName)] > ")"
}

REF: https://docs.microsoft.com/en-us/powershell/module/microsoft.powershell.core/about/about_prompts?view=powershell-7.2

Refs for enabling OpenSSH in Windows:

Installation: https://docs.microsoft.com/en-us/windows-server/administration/openssh/openssh_install_firstuse?tabs=powershell

Configuration:

https://docs.microsoft.com/en-us/windows-server/administration/openssh/openssh_server_configuration

Spam the Scammer

Got a phising SMS this week whis lead me to a fake DHL-website and asked me for personal data, credit card data and so on.

Though if they like collecting data so much I might help them and wrote the following script to help them collecting credit card data:

#!/bin/python3
import requests
import ccard
import pprint
import random
from termcolor import colored


target_addr="https://<SCAMMERS-DOMAIN>/PHP/send.php"
counter=0
while 1:
    cc=str(ccard.visa())
    cc_str=cc[0:4]+" "+cc[4:8]+" "+cc[8:12]+" "+cc[12:16]+" "
    cvv=(random.randint(100, 999))
    year=(random.randint(23, 27))
    month=(random.randint(1, 12))
    valid_date=str("{:02d}".format(month))+"/"+str("{:02d}".format(year))
    cc_data={"cc":cc_str,"exp":valid_date,"cvv":cvv,"type":"livraison"}
    r=requests.post(target_addr,json=cc_data)
    if r.status_code != 200:
        print(colored("ERROR - statuscode: "+r.status_code, "red"))
    else:
        counter=counter+1
        print(counter, end="\r")

The script will just generate face credit card numbers CVVs and face validation-dates and post it to the script, the scammer used to receive the data from the phising-site.

WSUS Server unable to obtain updates

If a WSUS server fails to obtain updates with the following error: “wsus the request failed with http status 404 not found” this might be because it still uses an old/outdated URL (https://fe2.update.microsoft.com/v6) to obtain the updates from.

This can be checked and changed with the following PS1 Snippet:

$server = Get-WsusServer
$config = $server.GetConfiguration()
# Check current settings before you change them 
$config.MUUrl
$config.RedirectorChangeNumber
# Update the settings if MUUrl is https://fe2.update.microsoft.com/v6
$config.MUUrl = "https://sws.update.microsoft.com"
$config.RedirectorChangeNumber = 4002
$config.Save()
iisreset
Restart-Service *Wsus* -v

PowerShell AD Snippet

Simple snippet to get a list when the passwort of a service user was set the last time.

Get-ADUser -Filter 'Name -like "svc*"' -Properties * | select Name,@{name ="pwdLastSet"; expression={[datetime]::FromFileTime($_.pwdLastSet)}}

Requires the Active Directory Powershell module to run.

Command must also be run in an elevated powershell session (Run as Administrator)

Otherwise the pwdLastSet attribute will not be obtained!

Sid To Username

Param
(
    [parameter(
        Mandatory=$true,
        HelpMessage="User SID"
        )
    ]
    [String]
    [alias("sid")]
    $user_sid
)
$objSID = New-Object System.Security.Principal.SecurityIdentifier $user_sid 
$objUser = $objSID.Translate( [System.Security.Principal.NTAccount]) 
$objUser.Value

Simply check if login on an ESXi works and return it’s license

Just a simple script to test ESXi Connectivity and return the current license state of the server by using PowerCLI

param(
    [Parameter(Mandatory = $true, HelpMessage = 'Provide username for login on ESXi')]
    [String] $username,
    [Parameter(Mandatory = $true, HelpMessage = 'Provide password for login on ESXi', ParameterSetName = 'Secret')]
    [Security.SecureString] $password

)

#check user/pwd
if($username -like "" -Or $password -like "")
{
    Write-Host -ForegroundColor Red "Username/Password seems wrong"
    exit(1)
}

#define domain
$domain="forensik.justiz.gv.at"

#disable certificate checking as we have self signed certs
Set-PowerCLIConfiguration -InvalidCertificateAction Ignore -Confirm:$false

$hosts="SITE01-ESX01","SITE01-ESX02","SITE01-ESX03","SITE01-ESX04","SITE01-ESX05","SITE01-ESX06","SITE02-ESX01","SITE02-ESX02","SITE02-ESX03","SITE02-ESX04","SITE02-ESX05","SITE02-ESX06" 



foreach($var_host in $hosts)
{
    Write-Host -ForegroundColor Yellow $var_host"."$domain
    Connect-VIServer -Server $var_host"."$domain -User $username -Password ([Runtime.InteropServices.Marshal]::PtrToStringAuto([Runtime.InteropServices.Marshal]::SecureStringToBSTR($password)))
    $(Get-VMHost).Name
    $(Get-VMHost).Version
    $(Get-VMHost).LicenseKey
    $(Get-VMHost).Uid
    Disconnect-VIServer $var_host"."$domain -WarningAction SilentlyContinue -Confirm:$false
    Write-Host -ForegroundColor Cyan "~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~"
}

Dovecot: convert mdbox to mbox format

Dovecot comes with a proprietary mailbox-format (sd/mdbox) that provides some benefits in regard of compression and performance but is not really readable with nothing else than an editor.

It seems that there are very little information on how to convert the sd/mdbox-fomat to mbox (at least nothing copy and paste like if you aren’t a dovecot admin and have no clue ;))

So here is one possible-way it could be archived:

To work around adapting the dovecot-config and running a dovecot-service for dsync to use, we can also pass configuration parameters (by default dsync uses the dovecot-configuration file stored at /etc/dovecot/dovecot.conf) directly to dsync.
With that trick there is no need to configure & start a dovecot service.

An example command to convert a mailbox in mdbox-format located in the users home dir under mail to mbox format would look like:

dsync -o "mail_location=mdbox:~/mail" backup mbox:~/dstest

Converting to other formats like maildir might require additional configuration parameters within the /etc/dovecot/dovecot.conf file as namespaces or similar.

IMPORTANT:
Override options specified via “-o” must be passed directly after the dsync command and before “backup”


For converting a mailbox the “backup” attribute is recommended as this will do a 1-way-sync.

Windows – Automatically power on printer on new Print job

My printer at home is powered of most of the time to save power as I’ll only print a couple of pages once every while.

As i was teached that technicians shall be lazy I use a Sonoff POW R2 to work around getting up and switching on the printer when I want to use it. The Sonoff was flashed with Tasmota to as I don’t want some chinese company to have some backdoor within my IOT-home net.

However, I still had to open up the sonnoff webpage every time and hit the power-on-button for my printer to come up and that’s still some work to do which could be avoided in honor of laziness.

So, the ingridents to a lazy but power saving printer are:

  • The Tasmota WEB API
  • Windows Event Log
  • Windows Task Sheduler

We can configure a Task that’s running in case a specific event log entry is appended to the event log and call the printer’s API to switch on the power every time somebody adds a new print job to the OS printer queue.

Event log config (eventvwr.msc)

The entry we want is: “Microsoft-Windows-PrintService/Operational” (Applications and Service Logs -> Microsoft -> Windows -> PrintService : Operational)
That log needs to be enabled first:

Once that’s done there will be new entries every time a new printjob is added:

The interesting part is the Event with the ID 800 -> that’s the one we are looking for as it logs that there is a new spooling job.

Create a Batch-Script to call the Tasmota API

That’s pretty easy. I suggest to simply create a batch script witht he following content:

@echo on
C:\Windows\System32\curl.exe "http://<IPADDRESS>/cm?cmnd=Power%%20On"

As curl already comes with newer installations we can simply use it for our call. A powershell could also be used, but by creting a batch script we do not have to deal with the PS-execution policy settings and getting them correct to work.

Create a Task (taskschd.msc)

A new task needs to be created. The Trigger is a specific event-log enty:

With the correct event configured:

As an action we just want to start a program which is the batchscript witht he content from above.

Once that’s done, the script will be run by the task scheduler every time someone hits the “print” button. Running the script will power up the printer automatically and Windows will print the page as soon as the printer is reachable. – so nomore getting up to power the printer manually 🙂

Kiwix – Make Wikipedia anD other websites availAble offline

In some cases it might be handy to have a website available offline for cases where no internet connection is available.

With Kiwix and the ZIM-package format it’s quite easy to do so. It can easily be run on a Raspberry and made accessible on the local network.

To automate updates of ZIM packages I wrote some little scripts which are available in the following Github repo: https://github.com/fawcs-at/zim-downloader

Information on how to use the scripts can be found in the readme in the GIT repo.

To automate the process of updating ZIM packages once a month the “updateZim.sh” should be added as a cronjob to your crontab:

e.g.:

#cat /etc/crontab
45 2    1 * *  <username> /<path_to_script>/updateZim.sh

Will start an update on ever 1st day of the month at quarter to 3 in the morning.