Azure PowerShell Runbook does not support System.Data.OleDb.OleDbConnection - azure

I am trying to open a connection with a ssas server and execute a dax query in order to extract table metadata, through a powershell runbook from an Azure Automation Account.
$daxConnectionString = "Provider=MSOLAP;Data Source=..."
I'm using the following code:
$daxConnectionString = "Provider=MSOLAP;Data Source=$daxServer;Initial Catalog=$daxCatalog;UID=$daxUserId;PWD=$daxPwd"
$daxConnection = New-Object -TypeName System.Data.OleDb.OleDbConnection
$daxConnection.ConnectionString = $daxConnectionString
$daxConnection.Open()
$daxCommand = $daxConnection.CreateCommand()
The system return the following exception:
System.Management.Automation.MethodInvocationException: Exception calling "Open" with "0" argument(s): "The .Net Framework Data Providers require Microsoft Data Access Components(MDAC). Please install Microsoft Data Access Components(MDAC) version 2.6 or later." ---> System.InvalidOperationException: The .Net Framework Data Providers require Microsoft Data Access Components(MDAC). Please install Microsoft Data Access Components(MDAC) version 2.6 or later. ---> System.Runtime.InteropServices.COMException: Retrieving the COM class factory for component with CLSID {2206CDB2-19C1-11D1-89E0-00C04FD7A829} failed due to the following error: 800736b1 The application has failed to start because its side-by-side configuration is incorrect. Please see the application event log or use the command-line sxstrace.exe tool for more detail. (Exception from HRESULT: 0x800736B1).
Is there a MDAC module available or can I solve this in an other way?
Thanks in advance,
Bart

To connect to the Analysis server. I'm not using a connection based on the MSOLAP provider but based on the ADOMD Client
daxConnectionString = "Data Source=$daxServer;Initial Catalog=$daxCatalog;User ID=$daxUserId;Password=$daxPwd"
$daxConnection = New-Object Microsoft.AnalysisServices.AdomdClient.AdomdConnection
$daxConnection.ConnectionString = $daxConnectionString
$daxConnection.Open()
$daxCommand = $daxConnection.CreateCommand()
With this in place the dataset can be filled like:
$daxAdapter = New-Object -TypeName Microsoft.AnalysisServices.AdomdClient.AdomdDataAdapter $daxCommand
$daxDataset = New-Object -TypeName System.Data.DataSet
$daxCommand.CommandText = $query
$nrRows = $daxAdapter.Fill($daxDataset)
The only thig is that the AdomdClient is not available in the RunBook and also not available in Modules... we create our own...
Download the nuget package from : Nuget.org
Rename the package extension to .zip
Search inside the package for the DLL called Microsoft.AnalysisServices.AdomdClient
Copy the Microsoft.AnalysisServices.AdomdClient.dll file and paste it inside a new folder.
Right-click on the folder and send it to zip.
Add the zip file to the runbook modules by "Adding a module"
Be sure that in the RunBook the library get's loaded by:
$assemblyPath = "C:\Modules\User\Microsoft.AnalysisServices.AdomdClient\Microsoft.AnalysisServices.AdomdClient.dll"
try {Add-Type -Path $assemblyPath}
catch { $_.Exception.LoaderExceptions }

You can use the OledbSql PowerShell Module to add in an azure automation for connection.
I have added the module in Azure Runbook. Which follows:
Import Module from local
From Gallery
Importing the module

Related

Binding Redirection in Azure Automation Account PowerShell Runbook

I'm in need of some help in setting up PowerShell binding redirection within an Azure Automation Account Runbook.
Essentially my Runbook calls a number of methods within two 3rd party .Net dlls, both provided by the same author. One of the dlls has a dependency on Newtonsoft.Json V12.0.1 and the other has a dependency on IdentityModel V4.0.0 which in turn has a dependency on Newtonsoft.Json V11.0.2. My Azure environment uses Windows PowerShell Desktop V5.1.15063.726. Before I do any work in my Runbook I call a function that loads all of the dlls in my imported module (the function calls the [System.Reflection.Assembly]::LoadFrom() method for each dll). I have verified that my imported dlls, including the Newtonsoft.Json.dll V12.0.1 have loaded successfully.
As expected, when Runbook execution hits a line that calls one of the 3rd party dll methods that needs the IdentityModel.dll an exception is thrown:
Exception calling "GetResult" with "0" argument(s): "Could not load file or assembly 'Newtonsoft.Json, Version=11.0.0.0, Culture=neutral, PublicKeyToken=30ad4fe6b2a6aeed' or one of its dependencies. The system cannot find the file specified." System.IO.FileNotFoundException.
This is a known issue and the consensus so far seems to be that I need to create and attach an event handler in PowerShell. One of the proposed solutions can be found here. My problem is with the line that attempts to attach the handler:
[System.AppDomain]::CurrentDomain.add_AssemblyResolve($onAssemblyResolveEventHandler)
When my Runbook hits this line the following exception is thrown:
Cannot find an overload for "add_AssemblyResolve" and the argument count: "1". TargetSite: Void CheckActionPreference(System.Management.Automation.Language.FunctionContext, System.Exception) StackTrace: at System.Management.Automation.ExceptionHandlingOps.CheckActionPreference(FunctionContext funcContext, Exception exception)
I can confirm that very limited testing seems to prove the code works in Windows 8.1 using the PowerShell ISE. I have searched extensively to see if there is a difference between how this code should be written in Azure and Windows Desktop, but no luck. Can anyone see what I am doing wrong? Am I missing any DLLs or using statements from my PowerShell script? If it is not possible to redirect binding in this way can anyone help with an alternative technique?
A code extract showing the creation and attachment of the event handler follows:
# Intercept resolution of binaries
$onAssemblyResolveEventHandler = [System.ResolveEventHandler]
{
param($sender, $e)
Write-Host "ResolveEventHandler: Attempting FullName resolution of $($e.Name)"
foreach($assembly in [System.AppDomain]::CurrentDomain.GetAssemblies())
{
if ($assembly.FullName -eq $e.Name)
{
Write-Host "Successful FullName resolution of $($e.Name)"
return $assembly
}
}
Write-Host "ResolveEventHandler: Attempting name-only resolution of $($e.Name)"
foreach($assembly in [System.AppDomain]::CurrentDomain.GetAssemblies())
{
# Get just the name from the FullName (no version)
$assemblyName = $assembly.FullName.Substring(0, $assembly.FullName.IndexOf(", "))
if ($e.Name.StartsWith($($assemblyName + ",")))
{
Write-Host "Successful name-only (no version) resolution of $assemblyName"
return $assembly
}
}
Write-Host "Unable to resolve $($e.Name)"
return $null
}
# Attach event handler
# This is the line that fails.
[System.AppDomain]::CurrentDomain.add_AssemblyResolve($onAssemblyResolveEventHandler)
I haven't been able to resolve the problem with getting binding redirection working in an Azure Automation Account - PowerShell runbook environment, but the author of the two 3rd party .Net dlls has kindly agreed to use NewtonSoft.Json version 11.0.2 for both dlls, so my problem disappears.

Data source name not found and no default driver specified". Failed to acquire connection "DestinationConnectionOLEDB"

I have created a SSIS package to import the excel to sql. I have set the connection string and excel file path by expression.
After that I'm trying to invoke package by c# WPF application by
Microsoft.SqlServer.Dts.Runtime.DTSExecResult and passing value of connection string and excel path. My code is as shown below
Application app = new Application();
Package package = null;
//Load the SSIS Package which will be executed
package = app.LoadPackage("D:\\EMS-Docs\\new\\SSIS\\SSISProject\\obj\\Development\\Package2.dtsx", null);
//Pass the varibles into SSIS Package
//Microsoft.SqlServer.Dts.Runtime.Variables myVars = package.Variables;
package.Variables["User::EXLPath"].Value = "D:\\EMS-Docs\\SSIS\\PRACTICAL_1901_LOT-2.xls";
package.Variables["User::SQLConn"].Value = GlobalClass.TransactionalDBConnectionString;
//Execute the SSIS Package and store the Execution Result
Microsoft.SqlServer.Dts.Runtime.DTSExecResult results = package.Execute();
The error
SSIS Error Code DTS_E_OLEDBERROR. An OLE DB error has occurred. Error code: 0x80004005.
An OLE DB record is available. Source: "Microsoft OLE DB Provider for ODBC Drivers" Hresult: 0x80004005 Description: "[Microsoft][ODBC Driver Manager] Data source name not found and no default driver specified".
Failed to acquire connection "DestinationConnectionOLEDB". Connection may not be configured correctly or you may not have the right permissions on this connection.
Error cause
The main error is:
"[Microsoft][ODBC Driver Manager] Data source name not found and no default driver specified"
Which means that the main problem is in the connection manager or the connection string.
Possible solutions
Make sure that you have set the connection manager and Data Flow Tasks Delay Validation property to True
Make sure that you are passing a valid connection string value by executing the package from visual studio with the same variable value.
Make sure that the application mode (32bit/64bit) is identical with the ODBC driver version. As example: if you have 32-bit ODBC driver installed, make sure that you are running the application in 32-bit mode
If you are connecting to SQL Server you can use SQL Native Client or Microsoft OLEDB Provider for SQL Server instead of ODBC provider
Additional Information
Also, you can refer to the following knowledge base article for more information about the error possible causes / solutions:
DATADIRECT "DATA SOURCE NAME NOT FOUND AND NO DEFAULT DRIVER SPECIFIED" ERROR

Moving away from Source-Safe but having problems installing SourceGear Vault on IIS 10

In order to keep my scripts I used to use Microsoft source safe but after many issues, I migrated to sourceGear Vault, which stores all the data in a few sql server databases, so that you can backup them, etc.
This question is specific to this version control system called SourceGear Vault.
In the past I had problems with SourceGear Vault installation and they were fixed.
Now again I am finding it not straight forward to install the SourceGear Vault client.
What I have done so far
I have used the following powershell commands to install the server and client:
msiexec /i VaultProServer64_10_0_0_30736.msi
msiexec /i VaultProClient_10_0_0_30736.msi
The server installation went on without major problems, other that you need to make sure you run the powershell above as Administrator. Same is valid for the client install.
Client install is ok too, the bit that I have got a problem is the IIS.
to find the version of IIS on powershell:
powershell "get-itemproperty HKLM:\SOFTWARE\Microsoft\InetStp\ | select setupstring,versionstring"
About the .NET version(s) I have installed
running the below Powershell script I get:
Get-ChildItem 'HKLM:\SOFTWARE\Microsoft\NET Framework Setup\NDP' -recurse |
Get-ItemProperty -name Version,Release -EA 0 |
Where { $_.PSChildName -match '^(?!S)\p{L}'} |
Select PSChildName, Version, Release, #{
name="Product"
expression={
switch -regex ($_.Release) {
"378389" { [Version]"4.5" }
"378675|378758" { [Version]"4.5.1" }
"379893" { [Version]"4.5.2" }
"393295|393297" { [Version]"4.6" }
"394254|394271" { [Version]"4.6.1" }
"394802|394806" { [Version]"4.6.2" }
"460798" { [Version]"4.7" }
{$_ -gt 460798} { [Version]"Undocumented 4.7 or higher, please update script" }
}
}
}
this is my current IIS SourceGear Environment:
The Application Pools
In the IIS Manager, click on Application Pools. there are multiple
pools for Vault. Check the Advanced Settings for each and look for
"Enable 32-bit Apps." That should be set to False.
I have all disabled the Enabled 32-bits Apps as you can see on the pictures below:
I show only one of the application pools but they are all set the same.
I had the following error but it is fixed now - see below for more info:
when I go to the http://localhost/vaultservice/index.html using google chrome,
I get the following error message:
HTTP Error 500.19 - Internal Server Error The requested page cannot be
accessed because the related configuration data for the page is
invalid.
Error Code 0x80070021
Config Error This configuration section cannot be used at this
path. This happens when the section is locked at a parent level.
Locking is either by default (overrideModeDefault="Deny"), or set
explicitly by a location tag with overrideMode="Deny" or the legacy
allowOverride="false".
This locked at parental level was fixed by doing the following:
I needed to change from read only to read/write some of the features: handler mappings and modules
before:
after:
The error message when using the application
This is the error message I am currently getting when connecting using the Vault client:
Unable to connect to http://mathura/VaultService. No server was found
at the specified URL. Please verify your network settings using the
Options dialog under the Tools menu in the Vault GUI Client. Web
Exception: The request failed with HTTP status 405: Method Not
Allowed.
How can I troubleshoot this and get to a healthy installation?
I fixed the problem.
when going to http://mathura/VaultService/VaultService.asmx
I was getting the following error:
The page you are requesting cannot be served because of the extension
configuration. If the page is a script, add a handler. If the file
should be downloaded, add a MIME map.
Then from the question below:
“The page you are requesting cannot be served because of the extension configuration.” error message
I had to check .NET Framework 4.5 Advanced Services > WCF Services >
HTTP Activation
and that solved my problem.
BEFORE:
AFTER:

SSIS package from ASP.net does not work on client but does on server

Description Of Environment
I have an SSIS task which executes from asp.net, the package gets data from excel files over UNC path and puts the data into a sql server databaase . I have deployed the SSIS to file system, it has windows authentication database connections and the IIS user has database access. I can log in as the AppPoolUser I have used to host the web application and open/modify the files in question so those basic permissions are there. Web App is compiled in x86.
When it works:
When run from web app in browser on server under my user or appPool user
When logged in as me on server running through BIDS
When logged in as AppPoolUser on server running through BIDS
When run from scheduled task on server using AppPoolUser
When it doesn't work:
When run from client browser i.e. not the machine that has IIS hosting the asp.net app
My Question
What is different about the client and server and how do I make it work? I was under the impression that when running the web app all connections go through the AppPool User so it should behave the same on any machine server included?
The Error returned to client browser
SSIS Error Code DTS_E_OLEDBERROR. An OLE DB error has occurred. Error code: 0x80004005. An OLE DB record is available. Source: "Microsoft Office Access Database Engine" Hresult: 0x80004005 Description: "The Microsoft Office Access database engine cannot open or write to the file '\\myserver\My folder\myfile.xlsx'. It is already opened exclusively by another user, or you need permission to view and write its data.". SSIS Error Code DTS_E_CANNOTACQUIRECONNECTIONFROMCONNECTIONMANAGER. The AcquireConnection method call to the connection manager "MyExcelFileConnection" failed with error code 0xC0202009. There may be error messages posted before this with more information on why the AcquireConnection method call failed. component "Excel Source" (1) failed validation and returned error code 0xC020801C. One or more component failed validation. There were errors during task validation.
c# Code running SSIS Package
string pkgLocation;
Package pkg;
Application app;
DTSExecResult pkgResults;
string result = string.Empty;
string dtsErrors = string.Empty;
try
{
pkgLocation = packagePath;
app = new Application();
pkg = app.LoadPackage(pkgLocation, null);
pkgResults = pkg.Execute();
foreach (DtsError local_DtsError in pkg.Errors)
dtsErrors += " " + local_DtsError.Description;
result = pkgResults.ToString();
}
catch (Exception exception)
{
result = exception.Message;
}

Enable RemoteApp Full Desktop programmatically

I am writing a powershell script to set up some HyperV VM's however there is one step I am having trouble automating. How do I check the box to allow Remote desktop access from the RemoteApp settings programmatically?
I can set up all of my customizations I need by doing
#build the security descriptor so the desktop only shows up for people who should be allowed to see it
$remoteDesktopUsersSid = New-Object System.Security.Principal.SecurityIdentifier($remoteDesktopUsersGroup.objectSid[0],0)
#get a copy of the WMI instance
$tsRemoteDesktop = Get-WmiObject -Namespace root\CIMV2\TerminalServices -Class Win32_TSRemoteDesktop
#set settings
$tsRemoteDesktop.Name=$ServerDisplayName
$tsRemoteDesktop.SecurityDescriptor= "O:WDG:WDD:ARP(A;CIOI;CCLCSWLORCGR;;;$remoteDesktopUsersSid)"
$tsRemoteDesktop.IconPath = $IconPath
$tsRemoteDesktop.IconIndex = $IconIndex
#push settings back to server
Set-WmiInstance -InputObject $tsRemoteDesktop -PutType UpdateOnly
however the instance of that WMI object does not exist until after you have the above box checked.
I attempted to use Set-WmiInstance to instantiate and set the settings at the same time but I keep getting errors like:
Set-WmiInstance :
At line:53 char:16
+ Set-WmiInstance <<<< -Namespace root\CIMV2\TerminalServices -Class Win32_TSRemoteDesktop -Arguments #{Alias='TSRemoteDesktop';Name=$ServerDisplayName;ShowInPortal=$true;SecurityDescriptor=$securityDescriptor}
+ CategoryInfo : NotSpecified: (:) [Set-WmiInstance], ArgumentException
+ FullyQualifiedErrorId : System.ArgumentException,Microsoft.PowerShell.Commands.SetWmiInstance
(also after running the command and getting the error it will delete the instance of Win32_TSRemoteDesktop if it already exited and un-check the box in the properties setting)
Is there any way to programmatically check that box or can anyone help with why Set-WmiInstance throws that error?
You could use the Remote Desktop Services Provider for Windows PowerShell module if you are running windows server 2008 R2.
You can read up about it on technet hear is the link.
I used this guide for all my needs .

Resources