Archiv der Kategorie: Powershell

Powershell: ODBC Schnittstellen erneuern

Sie kennen das vielleicht: endlich wurde der Datenbankserver erneuert und auf den neuesten Stand gebracht. Es gibt zahllose Anwendungen, die über Microsoft Access oder Excel auf den Datenbestand zugreifen. Dafür haben Sie vor Jahren eine ODBC Schnittstelle bei jedem User eingerichtet. Jetzt sind die User aber alle im HomeOffice oder aus zwei oder drei Usern wurden mittlerweile Dutzende, die mit ihren Programmen arbeiten.

Nun, dieser Beitrag aus dem Bereich „Coding“ erklärt. wie Sie diese Schnittstellen über Powershell bei allen Nutzern gleichzeitig aktualisieren können. Wie Sie so ein Script per Mail und mit der Hilfe von VBScript mühelos verteilen können, hatte ich in dem ersten Beitrag der Serie erklärt. Dieses Script wäre also jetzt eine neue Variante von „MeinPowershellScript.ps1“.

Import-Module Wdac
Remove-OdbcDsn -Name "MeineODBC_Verbindung" -Platform "32-bit" -DsnType "User"
Add-OdbcDsn "MeineODBC_Verbindung" -DriverName "ODBC Driver 17 for SQL Server" -DsnType User -Platform 32-bit -SetPropertyValue @("Server=SERVERADRESSE", "Trusted_Connection=Yes", "Database=MeineDatabase") -PassThru

Dazu muss ich einiges erklären. Import-Module Wdac ist zwingend notwendig. Damit werden in das Powershellscript die Windows Data Access Components geladen. Diese beinhalten die beiden nachfolgend genutzten Befehle.

Zunächst entfernen wir die vorhandene, veraltete ODBC Verbindung namens „MeineODBC_Verbindung“ mit Remove-OdbcDsn. Warum? Nun ich gehe davon aus, das der Name der ODBC Verbindung schon in zahlreichen Tools genutzt wird, z.B. als Datenquellen in AccessDatenbanken. Damit sie diese nicht neu umschreiben müssen, nutzen wir für die neue ODBC Verbindung die gleiche Bezeichnung. Und dazu müssen wir die alte erst entfernen.

Bitte beachten Sie, dass Sie auf User-Ebene in ihrem Script auch nur Benutzer-DSN löschen und erstellen können. System-DSN könnten von den vom User ausgeführten Script nur erstellt werden, wenn der User auch Systemadministrator ist. Daher nutzen wir als Schalter -DsnType „User“. Der Plattform Typ -32 oder 64 Bit – muss ggf. angepasst werden.

Dann folgt mit Add-OdbcDsn die Erstellung der neuen ODBC Verbindung. Der Name ist identisch mit der alten Verbindung. Die nachfolgenden Parameter müssen Sie natürlich anpassen. Zunächst der ODBC Treiber analog zum genutzten Datenbanksystem. In diesem Beispiel ist das ein Microsoft SQL Server. Für Oracle oder MySQL müssen Sie natürlich die entsprechenden Treiber installieren und dann den Treibernamen exakt angeben.

Dann folgen Plattformtyp und DsnType (auch hier wird wieder nur „User“ funktionieren. Der nachfolgende Teil hängt davon ab, mit welchem Sicherheitskonzept ihre User mit der Datenbank kommunizieren. In diesem Beispiel wird die ActiveDirectory Kennung der Users, die auch für den SQL Server gültig ist, an den Server durchgereicht. Haben Sie ein anderes Sicherheitskonzept, dann müssen Sie die Parameter entsprechend anpassen. Ich denke, dieses Beispiel dürfte eines der am häufigsten vorkommenden Szenarios sein. Alle weitere Parameter mit vielen Beispielen, finden Sie auf dieser Support-Seite von Microsoft.

Noch ein Hinweis: Wenn Sie die Tabellen der Datenbank in Access verbunden haben, dann müssen Sie diese in den Tabellenverknüpfungen einmalig aktualisieren. Das können Sie machen, bevor Sie die AccessDatenbank an diese User ausgeben. Wie das funktionieren könnte, hatte ich auch schon erklärt.

 

 

Powershell: Datei kopieren und AddIn aktualisieren

Ausgehend von meiner letzten Anleitung, in der ich beschrieben habe, wie man den Abruf eines Powershell-Scriptes im Netzwerk verteilen kann, zeige ich nun ein einfaches Script, mit dem eine Datei kopiert wird. In einem zweiten Schritt erkläre ich, wie man ein AddIn für Microsoft Office aktualisiert.

Durch die erste Anleitung wird klar, dass hier nicht nur ein einfacher Kopiervorgang erklärt wird – haben alle User Zugriff auf dieses Script, sei es durch einen Link in einer E-Mail oder durch einen Shortcut auf dem Desktop (beides hier beschrieben), dann erfolgt dieses Update überall.

Ein einfacher Kopiervorgang

Dieses Script ist also unser erstes „MeinPowershellScript.ps1“. Dieses Script kopiert eine AccessDatenbank mit dem Namen „MeineDatei.accdb“ von einem Server in ein lokales Verzeichnis des Users, der das Script aufgerufen hat

Copy-Item -Path "\\MeinServer\Quellordner\MeineDatei.accdb" -Destination "C:\LokalesVerzeichnis\MeineDatei.accdb"

Wenn Sie sich schon ein wenig mit Powershell auskennen, dann fragen Sie sich möglicherweise: was ist, wenn die Datei schon existiert? Wie verhält sich dann dieser Kopiervorgang?

Die Schalter -Force und -Confirm

Das Powershell Cmd-Let „Copy-Item“ überschreibt als Default Einstellung vorhandene Dateien. Der Schalter -Force, so denken einige logischerweise, wäre für das Überschreiben zuständig. Das ist nicht korrekt! „Copy-Item“ überschreibt immer, es sei den Sie nutzen den Schalter -Confirm. Der Schalter -Force ist dafür gedacht, auch blockierte Dateien zu überschreiben. Die Annahme, dass ein Weglassen des -Force Schalters das Kopieren verhindert, ist also falsch!

# Kopier- und Schreibvorgang auch dann, wenn die Zieldatei in Benutzung ist
Copy-Item -Path "\\MeinServer\Quellordner\MeineDatei.accdb" -Destination -Force "C:\LokalesVerzeichnis\MeineDatei.accdb"

# Kopier- und Schreibvorgang nur, wenn Vorgang bestätigt wird
Copy-Item -Path "\\MeinServer\Quellordner\MeineDatei.accdb" -Destination -Confirm "C:\LokalesVerzeichnis\MeineDatei.accdb"

Als weitere Variante könnte man den Kopiervorgang nur auslösen, wenn die Zieldatei nicht existiert. D.h. man prüft den Zielpfad und macht den Kopiervorgang von dieser Bedingung abhängig:

if ((Test-Path "C:\LokalesVerzeichnis\MeineDatei.accdb") -eq $false) {
    Copy-Item -Path "\\MeinServer\Quellordner\MeineDatei.accdb" -Destination "C:\LokalesVerzeichnis\MeineDatei.accdb"
    }

Ist Ihnen aufgefallen, dass hier kein „==“ als Vergleichsoperator genutzt wird, wie es bei anderen Programmiersprachen der Fall ist? Das ist eine Besonderheit von Powershell. „==“ oder „!=“ oder „>=“ – so etwas gibt es bei Powershell nicht! Auf dieser Seite, werden die Vergleichsoperatoren von Powershell erklärt. Sie werden sofort verstehen, dass durch die Variantenvielfalt mit Operatoren wie -contains oder -like viele Dinge vereinfacht werden, die Sie in anderen Programmiersprachen nur mit eigenen Funktionen implementieren können.

Konkretes Beispiel: Updates eines AddIn

Jetzt wollen wir bei allen unseren Usern im Netzwerk ein Excel-AddIn aktualisieren. Wir haben in dem AddIn Updates gemacht und die sollen allen Nutzern zur Verfügung gestellt werden. Analog zu dem einfachen Kopiervorgang aus dem ersten Beispiel wäre das:

$zieldatei = "$Env:USERPROFILE\AppData\Roaming\Microsoft\AddIns\MeinAddIn.xla"
Copy-Item -Path "\\MeinServer\Quellordner\MeinAddIn.xla" -Destination $zieldatei

Bereits in dem ersten Beispiel, als ich gezeigt habe, wie man mit Powershell einen Desktop-Shortcut erstellt, habe ich eine $Env Variable genutzt. Die gibt es in Powershell in vielen Varianten. Sie repräsentieren die Standortordner einer Windows-Installation oder gibt Infos zu User, Hardware oder dem Netzwerk. In diesem Fall wird das AddIn in den Roaming Ordner des Users geschrieben – dort gehört es ja auch hin.

Powershell: Updates an User im Netzwerk verteilen

In meinem Brotberuf habe ich sehr häufig die Situation, dass verschiedene Programme, Scripts, Datenbanken bei den Nutzern in meiner Abteilung aktualisiert oder ausgerollt werden müssen. Die Option, sich vor den Rechner eines jeden Users zu setzen und die Updates dort zu machen, war schon vor Corona und der Verlagerung von Arbeit in das Home-Office nicht wirklich effektiv.

Mit der Zeit findet man so einige Teil-Lösungen und baut sie zu einem Gesamtmechanismus zusammen. In diesem und folgenden Beiträgen möchte ich von den vielen Ideen, die mir geholfen haben, ein Gesamtbild erstellen und hier publizieren – vielleicht helfe ich damit anderen Menschen in meiner Position ebenfalls, die Abläufe zu verbessern.

Die Situation

Angenommen wir möchten bei all unseren Users ein Update lokal ausführen und wir wissen, dass wir den Nutzern nicht einfach sagen können, kopiere Datei von A nach B, erstelle eine neue ODBC-Datenbank-Schnittstelle, aktiviere das AddIn etc. und alles ist fein – schlicht, weil User damit überfordert sind und weil es auch nicht die Aufgabe von Usern ist, sich mit solchen Dingen auskennen zu müssen.

Die Ideallösung wäre also, wenn wir den Nutzern eine Mail schicken mit einer Anleitung, die letztendlich nur darin besteht, einen Button oder einen Link anzuklicken, der alles weitere erledigt.

Die ganzen Updates selbst machen wir mit Powershell. Mit einem Script, dass auf einem Server liegt. Davon gehe ich überhaupt generell aus – alle unsere Nutzer sind in demselben Netzwerk angemeldet, vermutlich autorisiert über VPN im Homeoffice.

Ein einfaches Update

Da man dem User kein Powershell Script einfach so schicken kann (die Policies in einem Unternehmen untersagen das vermutlich aus guten Gründen) behalten wir das eigentliche Script auf dem Server und senden dem User stattdessen den Link zu einer Datei namens UpdateScript.vbs – also eine VBScript Datei. Die ist relativ simple. Die Ausführung der Datei startet „MeinPowerShellScript.ps1“ auf dem Server und sieht so aus:

Dim pwShell
Set pwShell = CreateObject("Wscript.Shell")
pwShell.Run("powershell.exe \\MeinServer\MeinPowershellScript.ps1")

Sie speichern diese Datei auf dem Server. Der User bekommt nur den Link zugesendet. Nach einem Klick kann er das Ziel „Speichern“ oder „Ausführen“ – natürlich macht nur „Ausführen“ Sinn. Das sollte man den User in der Mail vielleicht erklären.

Einen Shortcut zu einem Script anlegen

Damit hätten wir ein einfaches Script, das ein PowershellScript direkt ausführt. Kommt das Ausführen dieses Powershell Scriptes häufiger vor, dann ist es vielleicht sinnvoll, für den User zu diesem Script einen Shortcut automatisch anzulegen. Das können wir machen, in dem wir vor das eigentliche Powershell-Script ein weiteres Powershell-Script voranschalten, dass den Shortcut auf dem Desktop des Users erzeugt.

Dim pwShell
Set pwShell = CreateObject("Wscript.Shell")
pwShell.Run("powershell.exe \\MeinServer\ErstelleDenShortcut.ps1")

Das Powershell Script „ErstelleDenShortcut.ps1“ sieht so aus – bitte Ihren Begebenheiten entsprechend anpassen:

$dir = "\\MeinServer\OrdnerMitPowershellScript\"
$w = New-Object -ComObject WScript.Shell
$desktop = [system.environment]::GetFolderPath("Desktop")

$link = $w.CreateShortcut("$desktop\Bezeichnung Shortcut.lnk")
$link.TargetPath = 'powershell.exe' 
$link.arguments = ' -file ' + "`"$dir\MeinPowershellScript.ps1`""
$link.workingDirectory = $dir
$link.save() > $null

Damit wird auf dem Desktop eines jeden Users, der dieses Script über das VBS Script aufgerufen hat, eine Verknüpfung zu „MeinPowershellScript.ps1“ mit der Bezeichnung „Bezeichnung Shortcut“ gelegt. Wann immer der User auf diesen Shortcut klickt, wird „MeinPowershellScript.ps1“ automatisch in Powershell aufgerufen und ausgeführt.

Sie erkennen wahrscheinlich, wieviel Potenzial hinter so einem Mechanismus steckt. In den nächsten Beiträgen werden wir was „MeinPowershellScript.ps1“ angeht ein bisschen konkreter. Ich zeige Ihnen, wie Sie

  • Dateien automatisch aktualisieren
  • ODBC Schnittstellen automatisch aktualisieren
  • Laufwerkszuordnungen
  • Ergebnisse von SQL Abfragen ausgeben
  • Server-Aliase updaten

können. Dieser Mechanismus ist also nicht nur für Updates interessant, sondern auch für die Ausführung wiederkehrender Aufgaben, die sich so automatisieren lassen. Hinter dem aufgerufenen Powershell-Script kann theoretisch ein komplexer Arbeitsablauf oder eine eigene Anwendung liegen.