OPHTHALMOSTAR Web Log

29. Oktober 2011

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.

10. August 2011

MEDISTAR-SQL-Server richtig neustarten

Wenn der Computer, auf dem die Oracle-Datenbank läuft, heruntergefahren wird, besteht die Gefahr, dass die Oracle-Datenbank nicht sauber geschlossen werden kann, weil Windows vor dem Herunterfahren geöffneten Programmen nur wenig Zeit zum Schließen gibt.

Am besten wird die Datenbank vor dem Shutdown sauber heruntergefahren – das beschleunigt den späteren  Neustart!

Mit Hilfe eines Powershell-Skripts lässt sich der Vorgang automatisieren.

MSReboot.ps1
# Skript ggfs. mit Administratorrechten neustarten
$identity = [System.Security.Principal.WindowsIdentity]::GetCurrent()
$princ = New-Object System.Security.Principal.WindowsPrincipal($identity)
if(!$princ.IsInRole(
[System.Security.Principal.WindowsBuiltInRole]::Administrator))
{
 $ps = [System.Diagnostics.Process]::GetCurrentProcess()
 $psi = New-Object System.Diagnostics.ProcessStartInfo $ps.Path
 $script = $MyInvocation.MyCommand.Path
 $prm = $script
 foreach($a in $args) {$prm += ' ' + $a}
 $psi.Arguments = $prm
 $psi.Verb = "runas"
 [System.Diagnostics.Process]::Start($psi) | Out-Null
 return;
}

# Oracle-Datenbank herunterfahren
$Password = "MeinPWD" # PASSWORT BITTE ANPASSEN
$SqlFile = "${env:temp}\Temp.sql" # Datei für SQL-Anweisungen
"shutdown normal;", "exit;" -join "`n" | Set-Content $SqlFile
sqlplus sys/$Password as sysdba '@'$SqlFile
Remove-Item -Path $SqlFile # Datei löschen

# MEDISTAR-Dienste beenden
Stop-Service "MEDISTAR ISAM"
Stop-Service "MEDISTAR RPCI"
Stop-Service OracleDBConsolemedistar
Stop-Service OracleMTSRecoveryService
Stop-Service OracleOraDb11g_home1TNSListener
Stop-Service OracleServiceMEDISTAR

# Computer neustarten
Restart-Computer

Wenn das Skript nicht startet, müssen Sie die Ausführungsrichtlinien anpassen.

18. September 2010

MEDISTAR- und Oracle-Dienste auf dem Heimrechner

Man kann ja darüber diskutieren, ob die Oracle-Datenbank für eine Kleinpraxis überdimensioniert ist. Unvernünftig wäre es auf jeden Fall auf einem Heimrechner, der in der Hauptsache für andere Dinge benutzt wird, die MEDISTAR- und Oracle-Dienste ständig laufen zu lassen.

Ich habe daher den Starttyp der Dienste von „Automatisch“ auf „Manuell“ geändert. Wenn ich MEDISTAR benutzen möchte, starte ich die Dienste durch den Aufruf eines Powershell-Skriptes.

Gegenüber einer normalen Batchdatei hat Powershell Vorteile: Erstens kann sich das Skript selbst Administratorrechte anfordern und zweitens informiert das Skript darüber, wann die Dienste laufen.
Wenn Sie auf Ihrem Rechner Powershell zum ersten mal benutzen, können Sie keine Skripte ausführen. Sie müssen zuvor die Ausführungsrichtlinien ändern.

OraStart.ps1
# Starte Skript mit Administratorrechten, falls ohne diese Rechte gestartet wurde.
$identity = [System.Security.Principal.WindowsIdentity]::GetCurrent()
$princ = New-Object System.Security.Principal.WindowsPrincipal($identity)
if(!$princ.IsInRole( `
[System.Security.Principal.WindowsBuiltInRole]::Administrator))
{
$powershell = [System.Diagnostics.Process]::GetCurrentProcess()
$psi = New-Object System.Diagnostics.ProcessStartInfo $powerShell.Path
$script = $MyInvocation.MyCommand.Path
$prm = $script
foreach($a in $args) {
$prm += ‘ ‘ + $a
}
$psi.Arguments = $prm
$psi.Verb = “runas”
[System.Diagnostics.Process]::Start($psi) | Out-Null
return;
}

# Starte Dienste, deren Starttyp von ‘Automatisch’ auf ‘Manuell’ geändert wurde.
Start-Service “MEDISTAR ISAM”
Start-Service “MEDISTAR RPCI”
Start-Service OracleMTSRecoveryService
Start-Service OracleOraDb11g_home1TNSListener
Start-Service OracleServiceMEDISTAR
Start-Service OracleDBConsolemedistar

# Starte, wenn gewünscht, einen MEDISTAR-Task, nachdem die Dienste gestarte wurden.
$title = “MEDISTAR-SQL-Starter”
$message = “MEDISTAR kann nun gestartet werden!`nSoll dies jetzt geschehen (Task-0)?”
$yes = New-Object System.Management.Automation.Host.ChoiceDescription “&Ja, Task-0 öffnen”, `
“Der MEDISTAR-Task wird gestartet.”
$no = New-Object System.Management.Automation.Host.ChoiceDescription “&Nein, nur beenden.”, `
“Powershell-Skript wird beendet.”
$options = [System.Management.Automation.Host.ChoiceDescription[]]($yes, $no)
$result = $host.ui.PromptForChoice($title, $message, $options, 0)
switch ($result) {
0 {D:\MEDISTAR\prg4\m42t.exe desk-0 -style medistar}
1 {“Sie haben Nein gewählt.”}
}

Das Skript kann in abgewandelter Form auch die Dienste beenden. Es muss nur „Start-Service“ durch „Stop-Service” ersetzt werden und Part 3 gelöscht werden.