0 Einleitung
0.1 fehlende Provider / Installation und Registrierung von Providern
Beispiel 1: "Provider=Microsoft.ACE.OLEDB.12.0;Data Source=$DatabaseName;"
Beispiel 2: "Provider = Microsoft.Jet.OLEDB.4.0;Data Source = $DatabaseName"
0.2 Einführungsbeispiele
Beispiel 1: Daten aus einer AccessDatebank auslesen (DataSet)
Beispiel2: Daten in eine AccessTabelle schreiben
1 Connectionstrings für x32 und x64 Architekturen
Beispiel 1: "Provider=Microsoft.ACE.OLEDB.12.0;Data Source=$DatabaseName;"
Beispiel 2: "Provider = Microsoft.Jet.OLEDB.4.0;..."
2 ADOX
Beispiel 1: Anlegen einer (leeren) Tabelle und anschließendes Auslesen aller Tabellen der Nordwind.mdb
Beispiel 2: DesignAnalyse einer bestimmten Tabelle in einer Accessdatenbank
Beispiel 3: Erstellen einer Tabelle mit zwei Spalten
3 Hilfreiche Links
0 Einleitung
Microsoft Access finde ich ein ziemlich geniales Programm, um einfach strukturierte Daten übersichtlich aufbereiten zu können.
In der Systemadministration fallen häufig größere Mengen an Daten an, für deren Aufbereitung Excel schon überfordert, aber ein SQLServer noch nicht notwendig ist.
Beispiele sind die Analyse von Eventlogdateien, oder laufende Performancemessungen.
Sollen beispielsweise die Einträge der Securitylogs aus mehreren Domaincontrollern analysiert werden, so kommen schnell einige hundertausend Events in einer Tabelle zusammen.
Bei der Verwendung von ADO.NET Skripten kommt es immer wieder zu Fehlermeldungen, dass der "...Provider ist nicht auf dem lokalen Computer registriert" sei.
|
Ausnahme beim Aufrufen von "Open" mit 0 Argument(en): "Der 'Microsoft.ACE.OLEDB.12.0'-Provider ist nicht auf dem lokalen Computer registriert." Bei Zeile:19 Zeichen:19 + $XLConnection.Open <<<< () + CategoryInfo : NotSpecified: (:) [], MethodInvocationException + FullyQualifiedErrorId : DotNetMethodException ..... |
Dies hat entweder damit zu tun, dass man einen Provider verwenden möchte, der für das verwendete Betriebssystem bzw. für die Betriebssystemarchitektur (32-bit/ 64-bit) nicht verfügbar ist, oder der im Skript verwendete Provider tatsächlich noch nicht registriert ist.
Lösungsmöglichkeiten:
-
Installation des Providers “Microsoft.ACE.OLEDB.12.0”
Microsoft Access Database Engine 2010 Redistributable (empfehlenswert, wenn kein Office 2010 installiert ist!). Damit könnt ihr dann auch auf Access oder Excel zugreifen, selbst wenn kein Office auf dem Client installiert ist.
-
Angleichung der Architektur von Betriebssystem und Office (32-bit/32-bit oder 64-bit/64-bit)
-
Unter 64-bit Betriebssystem mit 64-bit Office bevorzugt den Connectionstring "Provider=Microsoft.ACE.OLEDB.12.0;Data Source=$DatabaseName;"
- Habt ihr unter einem 64-bit Betriebssystem eine 32-bit Office installiert, verwendet bevorzugt den Connectionstring "Provider=Microsoft.ACE.OLEDB.12.0;Data Source=$DatabaseName;", nachdem ihr den ACE-Provider installiert habt (Siehe Punkt 1.). Ohne den ACE-Provider könnt ihr nur den $ConnectionString = "Provider = Microsoft.Jet.OLEDB.4.0;Data Source = $DatabaseName". Ihr müsst in beiden Fällen aber die 32-bit Version der Powershell nutzen:

Hier noch zwei einfache Beispiele, an denen ihr Erkennen könnt, ob der passenden Provider vorhanden ist.
Beispiel 1: "Provider=Microsoft.ACE.OLEDB.12.0;Data Source=$DatabaseName;"
|
$DatabaseName = "c:\temp\Nordwind.mdb" $Query = "SELECT Firma FROM Kunden" $ConnectionString = "Provider=Microsoft.ACE.OLEDB.12.0;Data Source=$DatabaseName;" # Connection Object erstellen $Connection = New-Object System.Data.OleDb.OleDbConnection $ConnectionString $Command = New-Object System.Data.OleDb.OleDbCommand $Query,$Connection $Connection.Open() #Daten zuerst in den Adapter laden, danach ins Dataset schreiben $Adapter = New-Object System.Data.OleDb.OleDbDataAdapter $Command $Dataset = New-Object System.Data.DataSet [void] $Adapter.Fill($DataSet) $Connection.Close() #Daten schreiben $DataSet.Tables | Select-Object -Expand Rows |
|
#mögliche Ausgabe, wenn der 12.0-Provider nicht installiert ist Ausnahme beim Aufrufen von "Open" mit 0 Argument(en): "Der 'Microsoft.ACE.OLEDB.12.0'-Provider ist nicht auf dem lokalen Computer registriert." Bei Zeile:6 Zeichen:17 + $Connection.Open <<<< () + CategoryInfo : NotSpecified: (:) [], MethodInvocationException + FullyQualifiedErrorId : DotNetMethodException |
Viele Beispiele im Internet benutzen als Connectionstring "Provider = Microsoft.Jet.OLEDB.4.0;..."
wie auch
Beispiel 2: "Provider = Microsoft.Jet.OLEDB.4.0;Data Source = $DatabaseName"
|
$DatabaseName = "c:\temp\Nordwind.mdb" $Query = "SELECT Firma FROM Kunden" $ConnectionString = "Provider = Microsoft.Jet.OLEDB.4.0;Data Source = $DatabaseName" # Connection Object erstellen $Connection = New-Object System.Data.OleDb.OleDbConnection $ConnectionString $Command = New-Object System.Data.OleDb.OleDbCommand $Query,$Connection $Connection.Open() #Daten zuerst in den Adapter laden, danach ins Dataset schreiben $Adapter = New-Object System.Data.OleDb.OleDbDataAdapter $Command $Dataset = New-Object System.Data.DataSet [void] $Adapter.Fill($DataSet) $Connection.Close() #Daten schreiben $DataSet.Tables | Select-Object -Expand Rows |
|
#Ausgabe, wenn der 4.0-Provider nicht installiert ist Ausnahme beim Aufrufen von "Open" mit 0 Argument(en): "Der 'Microsoft.Jet.OLEDB.4.0'-Provider ist nicht auf dem lokalen Computer registriert." Bei Zeile:9 Zeichen:17 + $Connection.Open <<<< () + CategoryInfo : NotSpecified: (:) [], MethodInvocationException + FullyQualifiedErrorId : DotNetMethodException |
Beispiel 1: Daten aus einer AccessDatebank auslesen (DataSet)
|
$DatabaseName = "c:\temp\Northwind.mdb" $Query = "SELECT Top 4 Firma FROM Kunden" $ConnectionString = "Provider=Microsoft.ACE.OLEDB.12.0;Data Source=C:\Temp\nordwind.mdb;" #Connection Object erstellen $Connection = New-Object System.Data.OleDb.OleDbConnection $ConnectionString $Command = New-Object System.Data.OleDb.OleDbCommand $Query,$Connection $Connection.Open() #Daten zuerst in den Adapter laden, danach ins Dataset schreiben $Adapter = New-Object System.Data.OleDb.OleDbDataAdapter $Command $Dataset = New-Object System.Data.DataSet [void] $Adapter.Fill($DataSet) $Connection.Close() #Daten schreiben $DataSet.Tables | Select-Object -Expand Rows |
|
#Ausgabe gekürzt Firma ----- Alfreds Futterkiste Ana Trujillo Emparedados y helados Antonio Moreno Taquería Around the Horn |
Dieses Beispiel funktioniert so nur mit einem Office unter 64-bit. Wenn ihr 32-Bit Office verwendet, muss die Zeile
$dsn = "Provider=Microsoft.ACE.OLEDB.12.0;Data Source=C:\Temp\nordwind.mdb;"
angepasst werden.
-
http://www.connectionstrings.com/Articles/Show/using-jet-in-64-bit-environments
-
http://www.microsoft.com/en-us/download/details.aspx?id=13255
Sollten Meldungen erscheinen, dass der Provider auf dem System nicht installiert ist, so kontrolliert eure OfficeVersion, ob diese tatsächlich unter 64-bit läuft
Beispiel 2: Daten in eine AccessTabelle schreiben
|
$adOpenStatic = 3 $adLockOptimistic = 3 $Connection = New-Object -com "ADODB.Connection" $RecordSet = New-Object -com "ADODB.Recordset" $Connection.Open("Provider=Microsoft.ACE.OLEDB.12.0;Data Source=C:\Temp\Database1.accdb;") $RecordSet.Open("Select * From Table1", $Connection,$adOpenStatic,$adLockOptimistic) $RecordSet.AddNew() $RecordSet.Fields.Item("ComputerName").Value = "Dom1Cli01" $RecordSet.Fields.Item("IPAddress").Value = "192.168.178.10" $RecordSet.Update() $RecordSet.Close() $Connection.Close() |
Liefern die folgende Beispiele Fehlermeldungen zurück, so liegt dies an der unterschiedlichen Verfügbarkeit der von den verschieden 32 und 64-bit Officeversionen benötigten Provider auf 32 und 64-Bit Betriebssystemen
Beispiel 1: "Provider=Microsoft.ACE.OLEDB.12.0;Data Source=$DatabaseName;"
|
$DatabaseName = "c:\temp\Nordwind.mdb" $Query = "SELECT Firma FROM Kunden" $ConnectionString = "Provider=Microsoft.ACE.OLEDB.12.0;Data Source=$DatabaseName;" #Connection Object erstellen $Connection = New-Object System.Data.OleDb.OleDbConnection $ConnectionString $Command = New-Object System.Data.OleDb.OleDbCommand $Query,$Connection $Connection.Open() #Daten zuerst in den Adapter laden, danach ins Dataset schreiben $Adapter = New-Object System.Data.OleDb.OleDbDataAdapter $Command $Dataset = New-Object System.Data.DataSet [void] $Adapter.Fill($DataSet) $Connection.Close() #Daten schreiben $DataSet.Tables | Select-Object -Expand Rows |
|
#mögliche Ausgabe Ausnahme beim Aufrufen von "Open" mit 0 Argument(en): "Der 'Microsoft.ACE.OLEDB.12.0'-Provider ist nicht auf dem lokalen Computer registriert." Bei Zeile:6 Zeichen:17 + $Connection.Open <<<< () + CategoryInfo : NotSpecified: (:) [], MethodInvocationException + FullyQualifiedErrorId : DotNetMethodException |
Viele Beispiele im Internet benutzen als Connectionstring "Provider = Microsoft.Jet.OLEDB.4.0;..."
wie auch
Beispiel 2: "Provider = Microsoft.Jet.OLEDB.4.0;..."
|
$DatabaseName = "c:\temp\Nordwind.mdb" $Query = "SELECT Firma FROM Kunden" $ConnectionString = "Provider = Microsoft.Jet.OLEDB.4.0;Data Source = $DatabaseName" #Connection Object erstellen $Connection = New-Object System.Data.OleDb.OleDbConnection $ConnectionString $Command = New-Object System.Data.OleDb.OleDbCommand $Query,$Connection $Connection.Open() #Daten zuerst in den Adapter laden, danach ins Dataset schreiben $Adapter = New-Object System.Data.OleDb.OleDbDataAdapter $Command $Dataset = New-Object System.Data.DataSet [void] $Adapter.Fill($DataSet) $Connection.Close() #Daten schreiben $DataSet.Tables | Select-Object -Expand Rows |
|
#Ausgabe Ausnahme beim Aufrufen von "Open" mit 0 Argument(en): "Der 'Microsoft.Jet.OLEDB.4.0'-Provider ist nicht auf dem lokalen Computer registriert." Bei Zeile:9 Zeichen:17 + $Connection.Open <<<< () + CategoryInfo : NotSpecified: (:) [], MethodInvocationException + FullyQualifiedErrorId : DotNetMethodException |
Diese Meldungen treten wiegesagt auf, wenn ihr auf einem 64-bit Betriebssystem eine 32-bit Version von Access installiert habt.
2 ADOX
Mit ADO.Net lassen sich die meisten Aufgaben mit prinzipiell baugleichen Skripten für verschiedene Datenquellen (Excel, SqlServer, Access und weitere) erledigen -> Datenzugriffe über ADO.Net - Connected Classes. Allerdings gibt es für Access ein paar Ausnahmen bei der Administration von Accessdatenbanken. Zumindest habe ich für folgende Aufgaben an AccessDbs keine Lösungen gefunden.
- Create Database
- Create/ Alter Table
Im Netz findet man Aussagen, dass dies nicht möglich sei, oder dass selbst anerkannte Spezialisten noch keine Lösung mit ADO.Net gefunden haben
Richard Siddaway's Blog "One thing that is obvious is that I am not checking the SQL to ensure that it is a CREATE TABLE command that is being passed in. This is a job for another time"
Den Ausweg bietet die ADOX-Bibliothek MSDN: ADOX Fundamentals (=Microsoft® ActiveX® Data Objects Extensions for Data Definition Language and Security (ADOX)). Nach dieser MSDN-Seite ist ADOX eine Erweiterung der ADO-Bibiliothek (nicht ADO.Net) und beinhaltet Funktionen zur Administration des Schemas (=Tabellen, Abfragen, Makros) einer Datenbank, sowie zur Verwaltung von Sicherheitsfunktionen.
Beispiel 1: Anlegen einer (leeren) Tabelle und anschließendes Auslesen aller Tabellen der Nordwind.mdb
|
Set-StrictMode -Version "2.0" Remove-Variable * force Clear-Host #$DatabaseName = "C:\Temp\Nordwind.accdb" $DatabaseName = "C:\Temp\Nordwind.mdb" $Provider="Provider=Microsoft.ACE.OLEDB.12.0" #Zusammenbau des ConnectionStrings $DataSource="Data Source=$DataBaseName" $ConnectionString = "$Provider;$DataSource;" #ConnectionObject erstellen und Öffnen $Conn = New-Object -ComObject 'ADODB.Connection' $Conn.ConnectionString = "$Provider;$DataSource;" $Conn.Open($null,$null,$null,0) #CatalogObject erstellen und öffnen $Catalog = New-Object -ComObject 'ADOX.Catalog' $Catalog.ActiveConnection = $Conn #TabellenObject erstellen und benennen $Table = New-Object -ComObject 'ADOX.Table' $Table.Name = "Neue Tabelle" #Tabelle an Datenbank (=Catalog) anfügen $Catalog.Tables.Append($Table) #Ausgabe aller Tabellen $Catalog.Tables | Sort Type,Name | Format-Table Name,Type -AutoSize #Schließen der Verbindung $Conn.Close() #getestet mit Office2010 und Win7 64bit/64bit |
|
#Ausgabe gekürzt
Name Type |
Es gibt in Access offenbar mehrere Typen von Tabellen
- AccessTable
- SystemTable
- Table
- View
Access- und System Table sind offenbar interne Systemtabellen von Access. er Typ Table gehört zu den auch in der GUI verwaltbaren Tabellen und der Typ View entspricht dort einer Abfrage/ Query.
Beispiel 2: DesignAnalyse einer bestimmten Tabelle in einer Accessdatenbank
Bei einer Datenbanktabelle ist neben den Daten vor allem das Design einer Tabelle entscheidend. Im DesignView von Access werden die Spalten definiert (Datentyp, Länge).

Per Skript kann man sich diese Informationen natürlich ebenso beschaffen
|
Set-StrictMode -Version "2.0" Remove-Variable * force Clear-Host #$DatabaseName = "C:\Temp\Nordwind.accdb" $DatabaseName = "C:\Temp\Nordwind.mdb" $Provider = "Provider=Microsoft.ACE.OLEDB.12.0" $TableName = "Artikel" #Zusammenbau des ConnectionStrings $DataSource="Data Source=$DataBaseName" $ConnectionString = "$Provider;$DataSource;" #ConnectionObject erstellen und Öffnen $Conn = New-Object -ComObject 'ADODB.Connection' $Conn.ConnectionString = "$Provider;$DataSource;" $Conn.Open($null,$null,$null,0) #CatalogObject erstellen und öffnen $Catalog = New-Object -ComObject 'ADOX.Catalog' $Catalog.ActiveConnection = $Conn #bestimmte Tabelle auswählen und analysieren $ArtikelTable = $Catalog.Tables | Where {$_.Name -eq $TableName} $ArtikelTable.Columns | Format-Table Name, DefinedSize, Type –AutoSize #$ArtikelTable.Columns | Format-Table * –AutoSize #Schließen der Verbindung $Conn.Close() #getestet mit Office2010 und Win7 64bit/64bit |
|
#Ausgabe Name DefinedSize Type ---- ----------- ---- Artikelname 40 202 Artikel-Nr 0 3 Auslaufartikel 2 11 BestellteEinheiten 0 2 Einzelpreis 0 6 Kategorie-Nr 0 3 Lagerbestand 0 2 Lieferanten-Nr 0 3 Liefereinheit 25 202 Mindestbestand 0 2 |
Die Spalte "Artikelname" besitzt den Type 202, was dem DataType "Text" entspricht. Die FieldSize (=DefinedSize) ist mit 40 festgelegt.
Alle möglichen Typewerte findet ihr selbstverständlich in der MSDN: ADO API Reference -> DataTypeEnum
Auszug aus der genannten MSDN-Tabelle:
| adSmallInt | 2 | Indicates a two-byte signed integer (DBTYPE_I2). |
| adInteger | 3 | Indicates a four-byte signed integer (DBTYPE_I4). |
| adCurrency | 6 | Indicates a currency value (DBTYPE_CY). Currency is a fixed-point number with four digits to the right of the decimal point. It is stored in an eight-byte signed integer scaled by 10,000. |
| adBoolean | 11 | Indicates a Boolean value (DBTYPE_BOOL). |
| adVarWChar | 202 | Indicates a null-terminated Unicode character string. |
Beispiel 3: Erstellen einer Tabelle mit zwei Spalten
|
Set-StrictMode -Version "2.0" Remove-Variable * force Clear-Host #$DatabaseName = "C:\Temp\Nordwind.accdb" $DatabaseName = "C:\Temp\Nordwind.mdb" $Provider="Provider=Microsoft.ACE.OLEDB.12.0" $TableName = "Neue Tabelle" #Zusammenbau des ConnectionStrings $DataSource="Data Source=$DataBaseName" $ConnectionString = "$Provider;$DataSource;" #ConnectionObject erstellen und öffnen $Conn = New-Object -ComObject 'ADODB.Connection' $Conn.ConnectionString = "$Provider;$DataSource;" $Conn.Open($null,$null,$null,0) #CatalogObject erstellen und öffnen $Catalog = New-Object -ComObject 'ADOX.Catalog' $Catalog.ActiveConnection = $Conn #TabellenObject erstellen, designen und benennen $Table = New-Object -ComObject 'ADOX.Table' $Table.Columns.Append("Marke",202,42) $Table.Columns.Append("Wert",6,4) $Table.Name = $TableName #Tabelle an Datenbank (=Catalog) anfügen $Catalog.Tables.Append($Table) #Ausgabe aller DesignInfos $Table.Columns | Format-List * #Schließen der Verbindung $Conn.Close() #getestet mit Office2010 und Win7 64bit/64bit |
|
#Ausgabe
Name : Marke |
Dieses Skript legt eine neue Tabelle in der AccessDatenbank "nordwind.mdb" an und fügt dieser Tabelle zwei Datenfelder hinzu. Die Definition der Typen findet ihr in dem Link aus Beispiel 2.
Um Daten in die Tabellen einzutragen oder daraus auszulesen, seht euch das Kapitel Datenzugriffe über ADO.Net - ADO.Net an
3 Hilfreiche Links
Working with Access Databases in Windows PowerShell
How Can I Create a Database with More Than One Table?
How Can I Use Windows PowerShell to Pull Records From a Microsoft Access Database?
Can I Query a Microsoft Access Database with a Windows PowerShell Script?
How Can I Add a Record to a Database Using Windows PowerShell?
2007 Office System Driver: Data Connectivity Components
Scripting Guys:

