Abfrage der aktiven Computer bzw. Sessions in MEDISTAR-SQL

Gut versteckt findet sich in MEDISTAR ein Dialogfenster für die Eingabe von SQL-Anfragen. Nützlich ist dieser Programmbestandteil durch seine Makrofähigkeit. Ich habe mir ein Makro gebaut, dass sich nach nur einem Klick zu diesem Dialog durchhangelt und abfragt, welche Benutzer bzw. Arbeitsplätze gerade MEDISTAR verwenden. Das ist nützlich vor irgendwelchen Arbeiten an der Datenbank (z.B. Updates, Backups, etc.), um noch geöffnete Tasks zu finden.

Sie gelangen zu dem Abfragefenster durch Eingabe der folgenden Befehle:

  • PSH“ um das Systemkommandofenster zu öffnen.
  • Dort führen Sie den Befehl „swrp sqlexec“ aus.
  • Nach Eingabe des Master-Passworts öffnet sich das SQL-Anfragefenster.
  • select distinct machine from v$session where username='MSUSER'” entlockt dem System die gewünschte Information.

PS: In OPHTHALMOSTAR 2.0 (coming soon!) sind die Makros natürlich eingebaut.

SQL-Anfrage

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.