Archiv der Kategorie: Coding

Powershell: ODBC Schnittstellen erneuern

Powershell

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

Powershell

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.

Kultur. Nutzerzahlen. Werbung. Teufelskreis?

Wer in den letzten Wochen das Kultur-Magazin verfolgt hat, der hat gesehen, dass sich dort einiges getan hat. Eigentlich ist so eine Seite ständig in Bearbeitung und nie ganz fertig. Man kommt aber irgendwann an einen Punkt, wo es nicht mehr um die Funktionen der Seite geht, sondern wo man sich nur noch um die Inhalte zu kümmern beginnt.

Ich habe meinen MAC reaktiviert. Dort gibt es einen externen Editor, der perfekt geeignet ist, um von überall offline Artikel zu schreiben, um sie dann automatisch hochzuladen. Alle Inhalte, die keine Artikel und keine Seiten in WordPress sind – zum Beispiel die vielen Infos in der Sidebar rechts – habe ich als als separate HTML Dateien ausgelagert, die ich mal eben ganz schnell editieren und aktualisieren kann. Für alle, die eine Möglichkeit suchen, einen HTML Inhalt von einer anderen Seite per Javascript in eine bestehende Seite zu laden – so geht’s. Einfach an die eigenen Gegebenheiten anpassen. jQuery Einbindung ist die Voraussetzung:

<script>
jQuery(function(){
jQuery(„#inhalt“).load(„https://www.meineseite.de/ExternerInhalt.html“);
});
</script>
<div id=“inhalt“></div>

Ich habe auch zum ersten Mal Werbung gemacht. Also richtig Werbung, in dem ich einen Beitrag auf Facebook „beworben“ habe. Das ist im Prinzip ganz einfach. Man nimmt einen Facebook-Beitrag – in meinem Fall ein Artikel, in dem ich auf die Funktionen zum Mitmachen hingewiesen habe – und sagt Facebook, dass er bei mehreren tausend Menschen als gesponserter Beitrag in deren Timeline erscheinen soll. Das Besondere: man definiert eine Zielgruppe, was in meinem Fall kulturinteressierte Menschen, insbesondere Künstler, Autoren, Selfpublisher sind. Der Post selber ist unaufdringlich, denn es geht mir tatsächlich nur darum, das Kultur-Magazin bekannter zu machen. Man gibt Facebook außerdem ein Budget und einen Zeitraum vor. Ich habe meine Seite zwei Wochen lang beworben und insgesamt 30,- ausgegeben. Da Facebook mit Instagram verbandelt ist, wird auch dort geworben. Das Ergebnis ist annehmbar. Es gibt tatsächlich eine ganze Menge neue Likes, neue Kontakte und es werden bisher unbekannte Personen auf das Kultur-Magazin aufmerksam. Diesen Beitrag habe ich für die Promotion genutzt:

FacebookPromotionJuli2019 1

Die Ergebnisse sind OK – was bei Ausgaben für Werbung immer ein „haptisches“ Problem ist: man hat hinterher nichts in der Hand. Man gibt Geld für etwas aus, das keinen direkten Nutzen zeigt.

FacebookPromotionJuli2019 2

Ich denke, dass ich solche Werbemaßnahmen wiederholen muß. Dann auch mal mit Google Ads.

Eine viel größere Baustelle ergibt sich aber derzeit aus den Rankingergebnissen meiner Artikel bei Google. Ich bearbeite jeden Artikel mit SEO Keywords, über die sich meine Artikel finden lassen sollen. Das fruchtet leider im Moment noch gar nicht. Der Ablauf ist relativ simpel. Nachdem der Artikel geschrieben wurde, wird über ein in WordPress integriertes SEO Tool (SEO = Search Engine Optimization) die Bearbeitung der Keywords und der Suchphrasen verfeinert. Diese sind dann wiederum Teil der Sitemap Files, die man über die Google Konsolen einreichen kann und die Google in regelmäßigen Abständen abruft und indexiert. So entstehen Google Einträge. Suche ich jedoch einen Artikel probehalber mit den Keywords ab, dann finde ich kein akzeptables Ranking. Beispiel: Mein Artikel über die Mondlandung vor zwei Wochen sollte über „Mondlandung“ und „Linksammlung“ als Stichworte auffindbar sein. Nach 15 Seiten in den Google-Ergebnissen habe ich die Suche aufgegeben.

Mir ist schon klar, dass eine Seite ohne Reputation keine Top-Ergebnisse von heute auf morgen erzielt, aber ich habe im Grunde überhaupt keine vernünftigen Ergebnisse abrufen können. Ich erinnere mich, dass ich vor einigen Jahren mit dem Artikel über die Camus Biographie von Iris Radisch auf Anhieb unter den ersten drei Ergebnissen in der Google Suche aufgetaucht bin. Was letztendlich ausschlaggebend ist, kann niemand mit Gewissheit sagen.



Meine Vermutung ist, dass meine neu gestartete Seite als eine Art Copy/Paste Crossposting wahrgenommen wird. Google meint, dass diese Inhalte nicht neu sind (was für meine alten Artikel auch stimmt) und setzt das Ranking dementsprechend. Ich muss da mal genauer nachforschen.

Eine weitere große Baustelle ist das Thema Werbung und Werbeanzeigen. Nach Monaten hat Google jetzt meine Seite für Google AdSense aktiviert. Das ist ein geniales Tool, um an den bekannten Stellen auf einer Seite Werbeanzeigen zu platzieren. Damit diese aber auch Traffic generieren, müssen die Besucher meiner Seite die Werbeanzeigen auch sehen und im besten Fall auch auf sie klicken. Das erreicht man, in dem man auf die Deaktivierung eines AdBlockers hinweist. Jetzt kam heute indirekt eine erste Rückmeldung, die sinngemäß lautete: Neue Seite und schon mit Werbung vollgestopft – keine Bereitschaft den AdBlocker abzustellen. Da ich meinen AdBlocker-Hinweis so eingestellt habe, dass er ein Betrachten meiner Seite ohne Deaktivierung des AdBlocker nichts zulässt, gehen möglicherweise viele Menschen gar nicht auf meine Seite. Sie sehen gar nicht, wie dezent die Werbung ist. Ich habe jetzt, um dem entgegenzuwirken, den Hinweis jetzt nicht „absolut“ eingestellt – er kann weggeklickt werden und die Seite erscheint dann ohne Werbung. Natürlich wäre auch naheliegend, einen AdBlocker für den Anfang komplett zu zulassen. Das habe ich aber kategorisch ausgeschlossen. Erst ohne Werbung die Besucher anlocken, um sie dann später mit Werbung zu vergraulen – das ist ein noch schlechterer Weg. Man kann nur auf die Einsicht hoffen, dass so eine Seite ohne Werbung auf lange Sicht nicht bestehen kann. Da ich ja selbst auch einfacher Internetnutzer bin und zum Beispiel diverse Tageszeitungen konsumiere, ist der Umgang mit dem AdBlocker aus meiner Sicht jetzt viel pragmatischer. Die Umsonstkultur zwingt Seitenbetreiber und Kunden zu einem bedachten Einsatz der AdBlocker. Verständnis ist hier das Wichtigste.

Trotz dieser Widrigkeiten: die Richtung stimmt. Ich freue mich sehr über die Zahl meiner Nutzer und weiterhin über eine geringe Absprungrate. Wenn ein Nutzer auf www.kultur-magazin.de ist, dann ist er gekommen, um zu bleiben.

EntwicklungJuli2019