MEDISTAR einfach neu installieren und Oracle-DB optimieren

Eine Neuinstallation von MEDISTAR-SQL ist relativ einfach. Bei mir funktionierte folgender Workaround:

  1. MEDISTAR-SQL Neuinstallations-DVD bzw. Programm besorgen und installieren. Dabei wird in der Regel nicht die neueste MEDISTAR-Version installiert, was nicht weiter stört.
  2. Anschließend alle Dateien des bisherigen MEDISTAR-Ordners über die Neuinstallation kopieren mit Ausnahme folgender Ordner und Dateien:
    – D:\MEDISTAR\INST\sql.ini
    – D:\MEDISTAR\oradata
  3. Den Export-Dump der bisherigen Installation in die neue Datenbank importieren.

Der wesentliche Punkt ist, dass es meiner bescheidenen Erfahrung nach nicht erforderlich ist, Quartalsupdates nachzuinstallieren, um die Software auf den neuesten Stand zu bringen. Das geschieht einfach durch das Kopieren der Dateien und den Import des aktuellen Dumps.

Nach gelungener Neuinstallation sollte man aber noch einige Einstellungen ändern bzw. optimieren. Um die erforderlichen Befehle nicht jedes Mal von Hand eingeben zu müssen, habe ich ein PowerShell-Skript erstellt, dass man einmalig nach einer Neuinstallation (oder später) auf dem MEDISTAR-Server ausführen sollte. Es mehrmals auszuführen schadet nicht, verändert dann aber nichts mehr.

Das Skript führt mit Hilfe von SQLPlus folgende Änderungen durch:
Die Datenbank wird in den Archivelog Modus gesetzt, um Online-Backups mit RMAN (Oracle Recovery Manager) zu ermöglichen. Als Ablagebereich wird standardmäßig die Flash Recovery Area, kurz FRA, genutzt. Hierfür wird die Archivierung eingeschaltet.
alter database archivelog;
archive log list;

Initialisierungsparameter im SPFILE werden geändert, um die Anzahl möglicher Verbindungen zu erhöhen. Der Default-Wert für PROCESSES ist 100, der für SESSIONS (1.1 * PROCESSES) + 5 und für TRANSACTIONS (1.1 * SESSIONS).
alter system set processes=930 scope=spfile;
alter system set sessions=1028 scope=spfile;
alter system set transactions=1030 scope=spfile;

Der Wert für die Lebensdauer der Passwörter wird korrigiert. Bei Usern sys, system und msuser darf kein Expiry-Date stehen.
alter profile default limit password_life_time unlimited;

Mit Hilfe der RMAN-Konsole erfolgen folgende Änderungen:
Für einen Full-Restore ist ein Controlfile-Backup notwendig. Deshalb wird der Parameter CONTROLFILE AUTOBACKUP auf “ON” gesetzt:
configure controlfile autobackup on;

Durch den Aufruf des ADR Command Interpreters erfolgen nachfolgende Einstellungen:
Alte Logs und Traces im Automatic Diagnostic Repository (ADR) können nach einer bestimmten Zeit automatisch gelöscht werden. Zuständig hierfür sind zwei Paramter SHORTP_POLICY (default 30 Tage, neu: 1 Woche) und LONGP_POLICY (default ein Jahr, neu: 1 Monat). „Purge“ sorgt bei einer länger bestehenden Installation für das sofortige Löschen älterer Dateien.
set control \(SHORTP_POLICY=168\);
set control \(LONGP_POLICY=720\);

Sie können das Skript hier herunterladen: MSPostInstallOptimization.zip
Wie immer geschieht die Anwendung auf eigene Gefahr. Alle MEDISTAR-Tasks sollten zuvor geschlossen werden.

MEDISTAR-SQL-Backup mit PowerShell erstellen

Der in der MEDISTAR-SQL-Version vorhandene Backup-Dienst automatisiert die Datensicherung, indem er einmal am Tag zu einer bestimmten Uhrzeit Kopien der ISAM-Datenbanken und einen Dump der Oracle-Datenbank erstellt. Die Dateien landen im Unterordner «Sicherung» des MEDISTAR-Verzeichnisses. Wenn man zusätzlich zu anderen Zeiten sichern möchte, kann dies mit folgendem PowerShell-Skript geschehen. Die Befehle für das Erstellen des Dumps der Oracle-Datenbank sind übrigens dem Log-Protokoll des Backup-Dienstes entnommen.

MSBackup.ps1
################################################################################
# Zweck: Exportiert ISAM-Datenbanken und erzeut einen Dump der Oracle-Datenbank.
#        Das Skript imitiert den MEDISTAR-Backup-Dienst. Es bietet als zusätz-
#        liches Feature die Möglichkeit, für jeden Wochentag einen anderen
#        Sicherungsort anzugeben (siehe Variable '$Location').
#        Außerdem können neben den ISAM-Datenbanken auch andere Dateien aus den
#        gleichen Ordnern gesichert werden (siehe Variable '$ExtTypes').
# Autor: Wilhelm Happe, © 2012
################################################################################
 
$PassWord = "XXXXXXXX"
$DumpFile = "ORACLE_EXP.DMP"
$IsamDirs = "HDATEN","INST","MED","PARA","PDATEN","PRAXIS","STAT"
$ExtTypes = "*.isd","*.isk","*.ism","PLPARA.*","oph*.mac"
$Isam_Log = "$Location\ISAM_EXP.log"
$MediStar = "${env:MEDISTARDIR}"
$Location = [string]::Concat($MediStar, "\Sicherung")
#$Location = [string]::Concat("D:\MSBackup", "_", (Get-Date).DayOfWeek)
 
$ErrorActionPreference = "SilentlyContinue"; $Index = 0
$Host.UI.RawUI.WindowTitle = "MEDISTAR-SQL-Export"
 
Function New-Folder {param([string]$Path)
  New-Item -itemtype directory -path "$Path" -force | out-null
  If ($?) {"$Path wurde erstellt."}
  Else {Write-Warning "$Path konnte nicht erstellt werden."; Sleep 3; Exit}}
 
If (Get-Process 'm42t' -ea 0) {
  Write-Warning "Sie müssen alle MEDISTAR-Tasks beenden."; Sleep 3; Exit}
 
Write-Host `nVorhandene Sicherungsdaten werden gelöscht: -fore blue -back white
Remove-Item -Path $Location\$DumpFile -force -ErrorAction 0
ForEach ($Item in $IsamDirs) {Remove-Item -Path $Location\$Item -recurse}
New-Folder -Path $Location
ForEach ($Item in $IsamDirs) {New-Folder -Path $Location\$Item}
 
Set-Content $Isam_Log -value ("Zeit: " + (Get-Date -format D) + ", " + `
  (Get-Date -format T) + "`nUser: " + $env:computername + "\" + `
  $env:username + "`n" + "¯" * 42)
 
# Der nachfolgende Block kopiert keine Dateien aus Unterordnern (s. unten)
If ($IsamDirs.Length -gt 0) {ForEach ($Folder in $IsamDirs) {
  Write-Host `nOrdner mit ISAM-Dateien werden kopiert: -fore blue -back white
  ForEach ($File in GCI "$MediStar\$Folder" -include $ExtTypes -recurse) {
    $FilePath = $MediStar -replace "\\","\\" -replace "\:","\:"
    $Destination = $File -replace $FilePath,$Location
    Copy-Item -path $File -dest $Destination -force -ea 0
    If ($?) {$Index ++; "$Destination"; AC $Isam_Log -value $Destination}
    Else {Write-Warning "$File wurde nicht kopiert"}}}}
Else {Write-Warning "`$IsamDirs enthält keine Elemente."; Sleep 3; Exit}
 
AC $Isam_Log ("_" * 42 + "`nAnzahl kopierter Dateien: " + $Index + "`nZeit: " `
  + (Get-Date -format D) + ", " + (Get-Date -format T))
 
Write-Host `nEs wird ein Export der Datenbank erstellt: -fore blue -back white
$SqlFile = "${env:temp}\Temp.sql"
@"
CREATE or REPLACE DIRECTORY exp_dir AS '$Location';
exit;
"@ | Set-Content $SqlFile  # Standard-Exportpfad neu setzten
sqlplus sys/$PassWord as sysdba '@'$SqlFile
expdp system/$PassWord directory=exp_dir dumpfile=$DumpFile `
  logfile=ORACLE_EXP.log schemas=MSUSER
@"
CREATE or REPLACE DIRECTORY exp_dir AS '$MediStar\Sicherung';
exit;
"@ | Set-Content $SqlFile  # Standard-Exportpfad zurücksetzten
sqlplus sys/$PassWord as sysdba '@'$SqlFile
Remove-Item -Path $SqlFile

Wenn der Wunsch besteht, Patientenbilder mitzusichern hilft der folgende Skriptblock. Enhalten ist die Anweisung, nur Bilder aus den letzten 90 Tagen zu kopieren.

# Der nachfolgende Block ermöglicht das Kopieren von Dateien aus Unterordnern.
# Z.B. werden Patientenbilider aus dem Unterordner PBILDER von PDATEN kopiert.
Write-Host `nEs werden zusätzliche Dateien kopiert: -fore blue -back white
$CopyFrom = @(
  "$MediStar\PDATEN\PBILDER\*.jpg"
	)
ForEach ($Item in $CopyFrom) {
  $Target = Split-Path $Item  # hinten trimmen (z.B.: '\_*.*')
  $Target = $Target.Replace("$MediStar\", "") # vorne trimmen
	If (!(Test-Path "$Location\$Target" -PathType Container))
		{New-Item "$Location\$Target" -Type Directory}
  Foreach ($i in Get-ChildItem $Item) {
    if ($i.LastWriteTime.Date -gt $(Get-Date).AddDays(-90))
      {
      Copy-Item $i.FullName $Location\$Target -ErrorVariable "Err"
	    If ($Err) {"Fehler beim Kopieren von $i.FullName"; Start-Sleep -s 5})
  }
}

MEDISTAR-SQL-Backup einlesen bzw. importieren

Vor gut einem Jahr habe ich bereits an dieser Stelle eine Batchdatei publiziert, die den Import der MEDISTAR-SQL-Sicherung automatisiert. Den gleichen Job erledigt das nachfolgende Powershell-Skript noch ein bisschen komfortabler.
Das Skript importiert den Datenbank-Dump (ORACLE_EXP.DMP) und kopiert die ISAM-Datenbankdateien in die entsprechenden Ordner.
Die Angaben in den ersten beiden Zeilen müssen individuell angepasst werden.

MSImport.ps1
# Zweck:  Importiert ISAM-Datenbanken und Oracle-Dump in eine bestehende
#         MEDISTAR-Installation. Vorhandene Daten werden überschrieben.
 
$DumpFolder = "T:\Sicherung"
$Password = "XXXXXXXX"
$DumpFile = "ORACLE_EXP.DMP"
$MediStar = "${env:MEDISTARDIR}"
 
$ErrorActionPreference = "SilentlyContinue"
$Host.UI.RawUI.WindowTitle = "Wiederherstellung der MEDISTAR-SQL-Sicherung"
 
Function Script-Exit {param([string]$Msg, $Sec) "`n";
  For ($Sec; $Sec -ge 0; $Sec --)
    {Write-Host "`r$Msg Skript wird beendet ($Sec)" -NoNewline;
    Start-Sleep 1}; Exit}
 
If (!(Test-Path -path $DumpFolder\$DumpFile)) {
  # 16 = Desktop, 17 = Computer, 18 = Netz
  $DumpFolder = 17; $Description = "Bitte wählen Sie den Ordner aus,`n" + `
  "der die Datei $DumpFile enthält."}
Else {$Description = "$DumpFile befindet sich im Ordner $DumpFolder.`n" + `
  "Sie können den Import starten. Klicken Sie auf OK."}
$Object = New-Object -comObject Shell.Application
$Folder = $Object.BrowseForFolder(0, $Description, "&H200", $DumpFolder)
If ($Folder -eq $null) {Script-Exit -Msg "Abbruch durch Benutzter." -Sec 3}
Else {$DumpFolder = $Folder.Self.Path; Write-Host "DumpFolder: $DumpFolder"}
If (!(Test-Path -path $DumpFolder\$DumpFile))
  {Script-Exit -Msg "$DumpFile nicht gefunden!" -Sec 3}
Else {Write-Host "$DumpFile gefunden."}
 
$Message = "Beim Restore werden die vorhandenen Daten gelöscht!"
$Object = New-Object -comObject wscript.shell
$Result = $Object.Popup($Message, 0, $myInvocation.MyCommand.Name, 1)
If ($Result -eq 2) {Script-Exit -Msg "Abbruch durch Benutzter." -Sec 3}
 
$CopyFrom = Get-Childitem $DumpFolder | where {$_.psIsContainer -eq $true}
ForEach ($Item in $CopyFrom) {
  $Item = -join ($DumpFolder, "\", $Item, "\*.*")
  $Folder = Split-Path (Split-Path $Item) -leaf
  If (Test-Path "$MediStar\$Folder") {
    Copy-Item -path $Item -dest $MediStar\$Folder -force -passthru}}
 
$SqlFile = "${env:temp}\Temp.sql"
@"
drop user msuser cascade;
commit;
CREATE or REPLACE DIRECTORY imp_dir AS '$DumpFolder';
exit;
"@ | Set-Content $SqlFile
sqlplus sys/$Password as sysdba '@'$SqlFile
 
impdp system/$Password directory=imp_dir dumpfile=$DumpFile full=yes `
logfile=imp_medistar.log
 
"shutdown immediate;", "startup;", "exit;" -join "`n" | Set-Content $SqlFile
sqlplus sys/$Password as sysdba '@'$SqlFile
 
Remove-Item -Path $SqlFile
Write-Host "Fertig. $DumpFolder\imp_medistar.log wird gestartet."
Invoke-Expression $DumpFolder\imp_medistar.log

Sie können die Datei auch herunterladen.

MEDISTAR-SQL-Datensicherung automatisieren

Unter MEDISTAR-SQL gibt es einen Backup-Dienst, der automatisch eine Siche­rung der Datenbank erstellt und im Ordner …\MEDISTAR\Sicherung ablegt. Damit liegt aber keineswegs eine ausreichende Datensicherung vor. Schließlich befinden sich die Backupdateien noch auf der Festplatte, auf der MEDISTAR und Oracle-Datenbank installiert sind. Bei einem Crash wären Original und Backup futsch.

Man ist also selbst dafür verantwortlich, dass diese Dateien auf einem anderen Medium gesichert werden. Das lässt sich mit Windows-Bordmitteln ein­rich­ten. Hierzu lassen wir z.B. auf einem Arbeitsplatz-PC eine Batch-Datei laufen, die an jedem Wochentag einen anderen Ordner für die Sicherung verwendet.

MSBackup.cmd
@echo off
set Heading=MEDISTAR-Backup-Sicherung
title=%Heading%
 

:: Pfade bitte individuell anpassen!
set MSPath=\\Server\d%%\MEDISTAR
set BackupDrive=E:

:: Wochentag ermitteln. Geht nicht mit CMD-Befehlen, daher VBS.
echo Wscript.Echo WeekdayName(Weekday(now,0),false,0) > %~n0.vbs
FOR /F "usebackq" %%a IN (`cscript.exe %~n0.vbs //nologo`) DO set weekday=%%a
del %~n0.vbs

:: LogDatei nicht in BackupFolder speichern; ROBOCOPY würde sie löschen!
set BackupFolder=%BackupDrive%\%~n0%weekday%
set TmpFile=%BackupDrive%\%~n0%weekday%.tmp
set LogFile=%BackupDrive%\%~n0%weekday%.log
set Options=/MIR /R:1 /W:1 /NC /NDL /NP /NS /TEE /FFT /Log+:%TmpFile%

:: MEDISTAR-Backup um Makrodateien und Patientenlisten ergänzen.
xcopy /d /h /i /f /k %MSPath%\INST\*.mac    %MSPath%\Sicherung\INST\*.*
xcopy /d /i /y /f /k %MSPath%\PARA\PLPARA.* %MSPath%\Sicherung\PARA\*.*

:: LogDatei anlegen, ggfs. überschreiben. Synchronisieren mit ROBOCOPY.
echo %Heading% am %weekday%, den %date% um %time:~0,8% Uhr. > "%TmpFile%"
robocopy %MSPath%\Sicherung %BackupFolder% %Options%

:: ASCII (TmpFile) nach Unicode (LogFile) umwandeln. TmpFile entsorgen.
cmd /u /c type %TmpFile% > %LogFile%
del %TmpFile%

:: LogDatei anzeigen und Batchdatei beenden ohne zu warten.
start %LogFile%

Wenn die Batchdatei richtig eingerichtet ist, wollen wir das DOS-Fenster nicht mehr sehen – wir bekommen ja nach erfolgter Datensicherung die Logdatei angezeigt. Aus diesem Grund starten wir die Batchdatei ohne sichtbares Fenster mit einem kleinen VB-Skript.

MSBStart.vbs
‚ Dieses VisualBasic-Skript startet MSBackup ohne sichtbares Fenster.
‚ Bitte beachten Sie, dass das Skript nicht MSBackup.vbs heißen darf,
‚ weil MSBackup.vbs von der Batchdatei gleichen Namens gelöscht wird!
Set WshShell = WScript.CreateObject("WScript.Shell")
WshShell.Run "MSBackup.cmd", 0, False
WshShell.Popup "MSBackup wird ausgeführt. Bitte warten...", 3, "Info"

Der dritte Schritt besteht darin, dass die Datensicherung täglich 10 oder 15 Minuten nach der Backup-Erstellung durch den MEDISTAR-Backup-Dienst mit Hilfe der Windows-Aufgabenplanung automatisch startet. Damit das VB-Skript die Batchdatei findet, muss unter «Starten in (optional)» der Pfad angegeben werden. Administratorrechte («mit höchsten Privilegien») sind erforderlich.

Weitere Informationen zu robocopy finden Sie hier.

Rücksicherung der Praxisdaten auf dem Heimrechner

Auch unter MEDISTAR-SQL (Oracle-Version) ist es möglich die Praxisdaten auf einem anderen Rechner zu importieren. Ich lasse mir in der Praxis den Inhalt des Ordners „…\MEDISTAR\Sicherung“ mit Hilfe von RobocopyMonitor automatisch auf ein USB-Stick sichern.
Der Import in die MEDISTAR-SQL-Installation auf dem Heimrechner gelingt bequem mit der folgenden Batch-Datei. Die Oracle- und MEDISTAR-Dienste müssen während des Imports bereits laufen!

MSRestore.cmd
@echo off & setlocal
color 1f
title Wiederherstellung der MEDISTAR-SQL-Sicherung
set DumpFile=ORACLE_EXP.DMP
set DumpFolder=G:\Sicherung
set MediStar=D:\MEDISTAR

rem DumpFolder 16 = Desktop, 17 = Arbeitsplatz, 18 = Netzwerkumgebung
echo DumpFolder = „%DumpFolder%“ > %~n0.vbs
echo If not CreateObject(„Scripting.FileSystemObject“).FolderExists(DumpFolder) Then >> %~n0.vbs
echo DumpFolder = 17 >> %~n0.vbs
echo End if >> %~n0.vbs
echo DumpFile = „%DumpFile%“ >> %~n0.vbs
echo Text = „Bitte wählen Sie den Ordner aus, der die zu importierende Datei „“ ^& DumpFile ^& „“ enthält.“ >> %~n0.vbs
echo Set objFolder = CreateObject(„Shell.Application“).BrowseForFolder(0,Text,“&H200″,DumpFolder) >> %~n0.vbs
echo If not objFolder is nothing then >> %~n0.vbs
echo WScript.Echo objFolder.Self.Path >> %~n0.vbs
echo End if >> %~n0.vbs
set DumpFolder=
for /f „delims=“ %%i in (‚cscript.exe %~n0.vbs //nologo‘) do set „DumpFolder=%%i“
if exist %DumpFolder%\%DumpFile% goto WARNING
echo MsgBox „%DumpFile% wurde nicht gefunden!“ ^& vbCrLf ^& _ > %~n0.vbs
echo „Der Vorgang wird abgebrochen.“, vbExclamation , „%~n0“ >> %~n0.vbs
cscript.exe %~n0.vbs //nologo
goto QUIT

:WARNING
echo WScript.Echo MsgBox („ACHTUNG!“ ^& vbCrLf ^& _ > %~n0.vbs
echo „Beim Restore werden die vorhandenen Daten gelöscht.“ ^& vbCrLf ^& vbCrLf ^& _ >> %~n0.vbs
echo „Möchten Sie den Vorgang fortsetzen?“, vbQuestion + vbYesNo, „%~n0“) >> %~n0.vbs
for /f „delims=“ %%i in (‚cscript.exe %~n0.vbs //nologo‘) do set „Answer=%%i“
if „%Answer%“==“6“ goto RESTORE
goto QUIT

:RESTORE
rem Zunächst werden die ISAM-Datenbanken ins MS-Verzeichnis kopiert.
xcopy „%DumpFolder%\hdaten“ „%MediStar%\hdaten“ /d /e /y /f /s
xcopy „%DumpFolder%\med“ „%MediStar%\med“ /d /e /y /f /s
xcopy „%DumpFolder%\para“ „%MediStar%\para“ /d /e /y /f /s
xcopy „%DumpFolder%\pdaten“ „%MediStar%\pdaten“ /d /e /y /f /s
xcopy „%DumpFolder%\praxis“ „%MediStar%\praxis“ /d /e /y /f /s
xcopy „%DumpFolder%\stat“ „%MediStar%\stat“ /d /e /y /f /s
xcopy „%DumpFolder%\inst“ „%MediStar%\inst“ /d /e /y /f /s

cls
rem Wenn der User gedroppt wurde, sind alle Daten aus der DB geloescht.
echo drop user msuser cascade; > %~n0.sql
echo commit; >> %~n0.sql
echo exit >> %~n0.sql
sqlplus sys/Passwort as sysdba @%~n0.sql

echo CREATE or REPLACE DIRECTORY imp_dir AS ‚%DumpFolder%‘; > %~n0.sql
echo exit >> %~n0.sql
sqlplus sys/Passwort as sysdba @%~n0.sql
impdp system/Passwort directory=imp_dir dumpfile=%DumpFile% full=yes logfile=imp_medistar.log

rem Es erfolgen finale Anpassungen, danach wird die DB neugestartet.
echo alter system set processes=930 scope=spfile; > %~n0.sql
echo alter system set sessions=1028 scope=spfile; >> %~n0.sql
echo alter system set transactions=1030 scope=spfile; >> %~n0.sql
echo shutdown immediate >> %~n0.sql
echo startup >> %~n0.sql
echo exit >> %~n0.sql
sqlplus sys/Passwort as sysdba @%~n0.sql
echo. & echo %DumpFolder%\imp_medistar.log wird gestartet.
start /b %DumpFolder%\imp_medistar.log
del %~n0.sql & echo. & pause

:QUIT
del %~n0.vbs

Das Passwort für den Benutzer sys müssen Sie in dem Skript passend ersetzen.

Lightning-Kalenderdateien von FTP-Server lokal sichern

Die Thunderbird-Erweiterung Lightning kann Termine auf einem FTP-Server speichern beziehungsweise als externen Kalender abonnieren.
Das ist sehr praktisch, wenn man von verschiedenen Rechnern auf den Terminkalender zugreifen möchte.

Ich möchte hier ein AutoHotkey-Skript vorstellen, mit dem sich die Kalender­dateien regelmäßig lokal sichern lassen. Es sollte nicht schwer fallen, das Skript an die eigenen Bedürfnisse anzupassen (Pfade, Dateinamen und Passwort).

ScriptTitle = Mozilla Calendar Backup
;» Folgende Zeilen müssen angepasst werden! «
ftpDomain = meineDomain.de
ftpPassWd = meinPasswort
ftpFolder = meinOrdnername
localPath = T:\USBStick\Lightning
;
SplitPath, localPath,,,,, localDrive
If !InStr(FileExist(localDrive), "D")
MsgBox, 48, %ScriptTitle%, «%localDrive%» wurde nicht gefunden!, 2
Else
{
;» Folgende Zeilen müssen angepasst werden! «
CalendarBackup("Kalender.ics")
CalendarBackup("Schulferien.ics")
CalendarBackup("Geburtstage.ics")
CalendarBackup("Feiertage.ics")
}
ExitApp
;
CalendarBackup(sourceFile, destFile = false)
{
Global
destFile := !destFile ? sourceFile : destFile
urlPath = ftp://%ftpDomain%:%ftpPassWd%@www.%ftpDomain%/%ftpFolder%
If not InStr(FileExist(localPath), "D")
FileCreateDir, %localPath%
TrayTip,, % sourceFile " wird nach " localPath " kopiert.",, 17
UrlDownloadToFile, %urlPath%/%sourceFile%, %localPath%\%destFile%
If Errorlevel
{
TrayTip,, %sourceFile% konnte nicht heruntergeladen werden., 5, 19
Sleep, 2000
}
}

Um das Skript ausführen zu können, müssen Sie den Code in eine Textdatei mit der Endung „.ahk“ speichern. Außerdem muss AutoHotkey installiert sein.

Mit Hilfe des Taskplaners oder noch einfacher der Aufgabenfunktion von Analog & Alarm Clock lässt sich das Skript automatisch regelmäßig starten.