SSIS Catalog and Project Deployment with PowerShell - sql-server

I'm trying to create a ssis catalog with power-shell
i'm getting a weird error. this is the code i'm running:
i took the code from msdn
$SQLserver = "BM-ELAD\DRC_BUG_RESTORE"
$Link = "false"
$pass = "123456"
# Load the IntegrationServices Assembly
[Reflection.Assembly]::LoadWithPartialName("Microsoft.SqlServer.Management.IntegrationServices")
# Store the IntegrationServices Assembly namespace to avoid typing it every time
$ISNamespace = "Microsoft.SqlServer.Management.IntegrationServices"
# Create a connection to the server
$sqlConnectionString = "Data Source=$SQLserver;Initial Catalog=master;Integrated Security=SSPI;"
$sqlConnection = New-Object System.Data.SqlClient.SqlConnection $sqlConnectionString
# Create the Integration Services object
$integrationServices = New-Object $ISNamespace".IntegrationServices" $sqlConnection
# Provision a new SSIS Catalog
$catalog = New-Object $ISNamespace".Catalog" ($integrationServices, "SSISDB", "$pass")
$catalog.Create()
and this is the error i'm getting:
GAC Version Location
--- ------- --------
True v2.0.50727 C:\Windows\assembly\GAC_MSIL\Microsoft.SqlServer.Management.IntegrationServices\13.0.0.0__89845dcd8080cc91\Microsoft.SqlServer.Management.IntegrationServices.dll
New-Object : The term 'New-Object' is not recognized as the name of a cmdlet, function, script file, or operable program. Check the spelling of the name, or if a path was included, verify
that the path is correct and try again.
At line:13 char:18
+ $sqlConnection = New-Object System.Data.SqlClient.SqlConnection $sqlConnectionSt ...
+ ~~~~~~~~~~
+ CategoryInfo : ObjectNotFound: (New-Object:String) [], CommandNotFoundException
+ FullyQualifiedErrorId : CommandNotFoundException
Has anyone ever encountered this problem? am i missing a file?
i tried this fix: failed fix and it didn't work.
my powershell version is 4.0
when i do this manually, it works.

Related

Could Not Load Assembly MICROSOFT.SQLSERVER.BATCHPARSER on 32-BIT environment

I'm posting my problem here, hoping someone may help me to figure the issue.
So, for one of my clients I've developed a PS script that retrieve a table for a database and export it as a CSV directly to a Blob Storage. My script works fine in a 64-Bit environment. However, I cannot run it in a 32-Bit environment. I need to run it in a 32-Bit environment because the scheduler used by the client is a 32-Bit tool.
On my side, I've tried every thing I've already found around the net on this subject with no luck.
My problem as I said above is that I fail to run my script on a 32-Bit environment. I'm putting a screenshot of booth environment so you can see what I'm having.
The Green square is the expected result. The Yellow one is the error I'm having.
The Blue squares shows booth SqlServer Modules I downloaded (x86 & 64).
I have the same behavior from a CMD SHELL.
So My questions are:
Is there anyway to make this script working on a 32-Bit environment?
Else Is there anyway to force a 32-BIT CMD SHELL to open a 64-Bit session on PowerShell ?
Here is the FUll PS SCript :
param (
[String]$SourceServer="" ,
[String]$SourceDatabase="" ,
[String]$DestinationStorageAccountName = "",
[String]$DestinationStorageAccountContainrerName= "",
[String]$DBUser = "",
[String]$DBUserPWD = ""
)
FUNCTION Write-ToBlobStorage{
[CmdletBinding()]
param (
[Parameter(Mandatory)][String]$ResultString,
[Parameter(Mandatory)][String]$DestinationStorageAccountName,
[Parameter(Mandatory)][String]$DestinationStorageAccountContainrerName,
[Parameter(Mandatory)][String]$FileName
)
write-host "Clear existing identies to keep cache fresh"
Clear-AzContext -force
write-host "Authenticate using the Managed identity"
$account = Connect-AzAccount -identity
if(-not $account.Context.Subscription.Id)
{
write-error "Failed to authenticate with the Managed identity. Ensure VM has a Managed identity enabled and is assigned the correct IAM roles"
return
}
write-host "Get storage context"
$context = New-AZStorageContext -StorageAccountName $DestinationStorageAccountName
write-host "Get storage Container"
$container=Get-AzStorageContainer -Name $DestinationStorageAccountContainrerName -Context $context
write-host "Writing Result to storage"
$content = [system.Text.Encoding]::UTF8.GetBytes($ResultString)
$container.CloudBlobContainer.GetBlockBlobReference("$FileName.csv").UploadFromByteArray($content,0,$content.Length)
}
#Import-Module 'Az.KeyVault' -Force
#Import-Module -Name 'C:\Program Files\WindowsPowerShell\Modules\SqlServer' -Force
Import-Module -Name 'C:\Program Files (x86)\WindowsPowerShell\Modules\SqlServer' -Force
$TLS12Protocol = [System.Net.SecurityProtocolType] 'Ssl3 , Tls12'
[System.Net.ServicePointManager]::SecurityProtocol = $TLS12Protocol
$Query = "SELECT ##SERVERNAME"
$Result = Invoke-Sqlcmd -ServerInstance $SourceServer -Database $SourceDatabase -Query $Query | ConvertTo-Csv -Delimiter '|' -NoTypeInformation
$ResultString = $Result -join "`r`n"
Write-ToBlobStorage -ResultString $ResultString -DestinationStorageAccountName $DestinationStorageAccountName -DestinationStorageAccountContainrerName $DestinationStorageAccountContainrerName -FileName "TMP_Flux"
write-host "--- ALL DONE---"
And Here is The error for the 32-Bit :
Invoke-Sqlcmd : Could not load file or assembly
'Microsoft.SqlServer.BatchParser, Version=15.100.0.0, Culture=neutral,
PublicKeyToken=89845dcd8080cc91' or one of its dependencies. The system cannot
find the file specified.
At C:\temp\ExportToBlobScript\ExportToBlob.ps1:87 char:11
+ $Result = Invoke-Sqlcmd -ServerInstance $SourceServer -Database $Sour ...
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : NotSpecified: (:) [Invoke-Sqlcmd], FileNotFoundEx
ception
+ FullyQualifiedErrorId : System.IO.FileNotFoundException,Microsoft.SqlServ
er.Management.PowerShell.GetScriptCommand
Write-ToBlobStorage : Cannot bind argument to parameter 'ResultString' because
it is an empty string.
At C:\temp\ExportToBlobScript\ExportToBlob.ps1:91 char:35
+ Write-ToBlobStorage -ResultString $ResultString -DestinationStorageAc ...
+ ~~~~~~~~~~~~~
+ CategoryInfo : InvalidData: (:) [Write-ToBlobStorage], Parameter
BindingValidationException
+ FullyQualifiedErrorId : ParameterArgumentValidationErrorEmptyStringNotAll
owed,Write-ToBlobStorage
--- ALL DONE---
And Here is the result for the 64-Bit:
Clear existing identies to keep cache fresh
Authenticate using the Managed identity
Get storage context
Get storage Container
Writing Result to storage
--- ALL DONE---
Many Thanks for all of you suggestions.
Not sure. But since you're only using Invoke-SqlCmd to run a query, you can eliminate the dependence on the SqlServer powershell module by using ADO.NET directly from PowerShell. The SQL Server client libraries are part of the .NET framework, so they will be available on any Windows box. So something like:
function Invoke-SqlCmd-Custom{
[CmdletBinding()]
param (
[Parameter(Mandatory)][String]$ServerInstance,
[Parameter(Mandatory)][String]$Database,
[Parameter(Mandatory)][String]$Query
)
$con = new-object System.Data.SqlClient.SqlConnection
$con.ConnectionString = "Server=$ServerInstance;Database=$Database;Integrated Security=true"
try
{
$con.Open()
$cmd = $con.CreateCommand()
$cmd.CommandText = $Query
$dt = new-object System.Data.DataTable
$rdr = $cmd.ExecuteReader()
$dt.Load($rdr)
return $dt.Rows
}
finally
{
$con.Close()
}
}

Deploy SSIS-Package with PowerShell

I'm trying to deploy an .ispac-file via PowerShell to SQL Server (2017). So far I have already downloaded the SQL Server PowerShell Module and of course SSIS is installed as well (Version 15.0.2000.93).
The PowerShell script I'm trying to run is pretty much the same as the one from the documentation:
# Variables
$SSISNamespace = "Microsoft.SqlServer.Management.IntegrationServices"
$TargetServerName = "name"
$TargetFolderName = "name"
$ProjectFilePath = "path"
$ProjectName = "name"
# Load the IntegrationServices assembly
$loadStatus = [System.Reflection.Assembly]::LoadWithPartialName("Microsoft.SQLServer.Management.IntegrationServices, "+
"Version=14.0.0.0, Culture=neutral, PublicKeyToken=89845dcd8080cc91, processorArchitecture=MSIL")
# Create a connection to the server
$sqlConnectionString = `
"Data Source=" + $TargetServerName + ";Initial Catalog=master;Integrated Security=SSPI;"
$sqlConnection = New-Object System.Data.SqlClient.SqlConnection $sqlConnectionString
# Create the Integration Services object
$integrationServices = New-Object $SSISNamespace".IntegrationServices" $sqlConnection
# Get the Integration Services catalog
$catalog = $integrationServices.Catalogs["SSISDB"]
# Create the target folder
$folder = New-Object $SSISNamespace".CatalogFolder" ($catalog, $TargetFolderName,
"Folder description")
$folder.Create()
Write-Host "Deploying " $ProjectName " project ..."
# Read the project file and deploy it
[byte[]] $projectFile = [System.IO.File]::ReadAllBytes($ProjectFilePath)
$folder.DeployProject($ProjectName, $projectFile)
The error occurs on line 18:
$integrationServices = New-Object $SSISNamespace".IntegrationServices" $sqlConnection
and says that the assembly or a dependency of it can't be found (see below):
"Microsoft.SqlServer.Dmf.Common,Version=13.0.0.0, Culture=neutral,
PublicKeyToken=89845dcd8080cc91"
Also, when I try 'Start PowerShell' by rightclicking on the Integration Services Catalog in SSMS(18.5), I get the error:
Value cannot be null. Parameter name: value(mscorlib)
I don't know if the errors are connected in some way, but I hope it helps finding the problem.
I ran the PowerShell as administrator and there are no restrictions to reading or executing DLLs.
Thanks alot in advance and I'm happy with any hints you can give me!

Comparing ALL settings between two separate powershell windows in the ISE?

TL;DR - I have a window in the ISE where I somehow got my script to work. If I start a new window (aka session?) in the ISE and copy/paste the code, the script fails. I'm trying to figure out what is different between the sessions so that I can get it to reliably work. I'm hoping there's some setting or something that I set in one that's not in the other, but I'm clearing variables between runs (see below) so I just don't know.
Long version:
I have a Powershell SMO/SQLServer script that works in one window in the ISE that uses ScriptTransfer(), which is a module inside the SQLServer module.
When I create a new window (aka new session) and copy/paste the code and run it against one particular server/database, the scripttransfer fails. I have no idea how I managed to get it working, but I want to duplicate that. The code works on most of my databases, but fails on one particular one, and there's no easy way to figure out what's going wrong inside that module, and the error message I get back is:
Exception calling "ScriptTransfer" with "0" argument(s): "Script transfer failed. "
At line:68 char:1
+ $transfer.ScriptTransfer()
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : NotSpecified: (:) [], MethodInvocationException
+ FullyQualifiedErrorId : FailedOperationException
Here's the code. It works on most databases, but I've got one DB that's causing these errors. Including it here just to be complete.
Remove-Variable -Name * -ErrorAction SilentlyContinue #allows us to run repeatedly in same session for testing.
import-module sqlserver #yes, necessary, at least so that you know if the scripttransfer fails, you need to get a newer version.
$servername = "mydb"
$databasename = "myserver"
$workingdirectory ="c:\temp\backup"
"servername is $servername"
"databasename is $databasename"
"uploadtos3 is $uploadtoS3"
"accesskey is $accesskey"
"secretkey is $secretkey"
"workingdirectory is $workingdirectory"
"bucketname is $bucketname"
"regionname is $regionname"
"s3path is $s3path"
####################
# 0 - Declarations #
####################
$credentials = set-awscredentials -accesskey $accesskey -secretkey $secretkey
$sql_server = $servername
$DBToScript = $databasename
$path = $workingdirectory #I'd use a UNC path here
################################
# 1 - Scripting out the CREATE #
################################
$SMOServer = New-Object -TypeName Microsoft.SqlServer.Management.Smo.Server -ArgumentList "$sql_server"
$db = $SMOServer.Databases[$DBToScript]
$create_database = $db.Script() -replace("\d+KB","100mb") -replace("\d+mb","100mb") -replace("\d+GB","100mb")
#while I couldn't get it to script out the GO terminators (ScriptBatchTerminator), it doesn't need it for the create.
$create_database |Out-File "$path\$($dbtoscript)_db_create.sql" -Force -Encoding ascii -Append
#using out-file since I can't figure out which setting uses filename.
#####################################
# 2 - Scripting out all the objects #
#####################################
#using transfer as it seems more straightforward.
$transfer = new-object -TypeName Microsoft.SqlServer.Management.Smo.Transfer #-ArgumentList $db
$transfer.Database = $db
$transfer.CopyAllObjects = $true
$transfer.CopySchema = $true
$transfer.CopyAllSchemas= $true
$transfer.Options.Indexes = $true
$transfer.Options.ScriptBatchTerminator = $true # this only goes to the file
$transfer.Options.filename = "$path\$($dbtoscript)_db_objects.sql"
$transfer.Options.ExtendedProperties= $true # yes, we want these
$transfer.Options.DRIAll= $true # and all the constraints
$transfer.Options.Indexes= $true # Yup, these would be nice
$transfer.Options.Triggers= $true # This should be included when scripting a database
$transfer.Options.ScriptBatchTerminator = $true # this only goes to the file
$transfer.Options.IncludeHeaders = $false #pshaw
$transfer.Options.ToFileOnly = $true #no need of string output as well
$transfer.Options.IncludeIfNotExists = $false # not necessary but it means the script can be more versatile
"test"
# This first ScriptTransfer MUST stay! Otherwise it leaves out the WITH EXECUTE AS CALLER on CLR SPs
$transfer.ScriptTransfer() |out-null
$transfer.ScriptTransfer()

Errors using DacServices to unregister a data tier

Upgrading my code from DacStore to work in SQL Server 2016 and running into issues with DacServices. The goal here is to unregister the data tier of a preexisting database before updating the schema.
Code snippet:
$serverconnection = New-Object System.Data.SqlClient.SqlConnection
If (!$uid -And !$pwd){
$serverconnection.ConnectionString = "Server = $server; Database = $database; Integrated Security = True;"
}
Else{
$serverconnection.ConnectionString = "server = $server; Database = $database; Integrated Security = False; User ID = $uid; Password = $pwd;"
}
# Load the DAC assembly
$validate = Test-Path $dacfxPath
if (!$dacfxPath){
throw 'No usable version of Dac Fx found.'
}
Add-Type -Path $dacfxPath # Attempt to load DAC assembly
$DacService = New-Object Microsoft.SqlServer.Dac.DacServices($serverconnection)
$dacName = $database
## Only delete the DAC definition from msdb, the associated database remains active.
$DacService.Unregister($dacName)
Error received when creating DacServices object:
New-Object : Exception calling ".ctor" with "1" argument(s): "Format of the initialization string does not conform to
specification starting at index 0."
At C:\Users\Administrator\AppData\Local\Temp\2\_ir_sf_temp_0\UnregisterDataTier.ps1:34 char:15
+ ... acService = New-Object Microsoft.SqlServer.Dac.DacServices($servercon ...
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : InvalidOperation: (:) [New-Object], MethodInvocationException
+ FullyQualifiedErrorId : ConstructorInvokedThrowException,Microsoft.PowerShell.Commands.NewObjectCommand
My connection string appears correct, and worked in the past. What else could I be doing incorrectly?
Update: Specifying in the DacServices constructor arg that it was a connection string seemed to fix the issue.
$DacService = New-Object Microsoft.SqlServer.Dac.DacServices($serverconnection.Connec‌​tionString)
Having an issue with the Unregister() method now, but one step closer!

SMO.Transfer: cannot convert type "database" to type "database"

Here is a powershell script:
[string] $server = "devserver\mssql"; # SQL Server Instance
[string] $database = "ftg"; # Database with the tables to script out.
[string] $folder = "d:\FT\FTProject\"; # Path to export to
[string] $SQLLogin = "Sa";
[string] $SQLPass = "Sa1234";
# Reference to SMO
[void][System.Reflection.Assembly]::LoadWithPartialName('Microsoft.SqlServer.SMO');
Write-Output ((Get-Date -format yyyy-MM-dd_HH-mm-ss) + ": Started ...");
$con = New-Object Microsoft.SqlServer.Management.Common.ServerConnection($server, $SQLLogin, $SQLPass);
$srv = New-Object Microsoft.SqlServer.Management.SMO.Server($con);
$db = New-Object Microsoft.SqlServer.Management.SMO.Database($srv, $database);
#Use SMO Transfer Class by specifying source database
#you can specify properties you want either brought over or excluded, when the copy happens
$ObjTransfer = New-Object -TypeName Microsoft.SqlServer.Management.SMO.Transfer;
$ObjTransfer.Database = $db
At last line an error occurs:
Exception setting "Database": "Cannot convert the "[ftg]" value of type "Microsoft.SqlServer.Management.Smo.Database" to type "Microsoft.SqlServer.Managem
ent.Smo.Database"."
At D:\FT\FTProject\Setup\transfer.ps1:31 char:1
+ $ObjTransfer.Database = [Microsoft.SqlServer.Management.SMO.Database] $db
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : NotSpecified: (:) [], SetValueInvocationException
+ FullyQualifiedErrorId : ExceptionWhenSetting
I also tryed to set $db as follows:
$db = $srv.Databases[$database]
What is wrong?
Try the following:
$db = $srv.Databases[$database]
...
$ObjTransfer = New-Object -TypeName Microsoft.SqlServer.Management.SMO.Transfer -ArgumentList $db
This should create the Transfer object using $db as the Source Database.
See example at MSDN: Transferring Schema and Data from One Database to Another in PowerShell
I think it because different versions of Microsoft.SqlServer.Smo.dll and Microsoft.SqlServer.SmoExtended.dll were loaded.
I get the same error when i loaded first assembly in 10 version and another one in 12.
When i loaded both of them explicitly in the same version everything worked fine.
Add-Type -path "C:\Windows\assembly\GAC_MSIL\Microsoft.SqlServer.Smo\12.0.0.0__89845dcd8080cc91\Microsoft.SqlServer.Smo.dll"
Add-Type -path "C:\Windows\assembly\GAC_MSIL\Microsoft.SqlServer.SmoExtended\12.0.0.0__89845dcd8080cc91\Microsoft.SqlServer.SmoExtended.dll"

Resources