invoke-sqlcmd - can I change the ApplicationName? - sql-server

I'm running queries against SQL servers using invoke-sqlcmd and invoke-sqlcmd2.
Is there a way to change the ApplicationName that it runs as? When I run a profiler trace, I see the queries are run by ".Net SqlClient Data Provider", and I'd like to change that.
Any help greatly appreciated

Okay, futzed with the invoke-sqlcmd2 script by Chad Miller and came up with this:
Line 45, after "datarow" I added a comma, then:
[Parameter(Position=9, Mandatory=$false)] [string]$ApplicationName='Powershell'
Then modified the connection strings (about line 54):
if ($Username)
{ $ConnectionString = "Server={0};Database={1};User ID={2};Password={3};Application Name={5};Trusted_Connection=False;Connect Timeout={4}" -f $ServerInstance,$Database,$Username,$Password,$ConnectionTimeout,$ApplicationName }
else
{ $ConnectionString = "Server={0};Database={1};Integrated Security=True;Application Name={3};Connect Timeout={2}" -f $ServerInstance,$Database,$ConnectionTimeout,$ApplicationName }
The default Appname is now "Powershell", but can be changed by using the -ApplicationName parameter.

Include Application Name=MyAppName; in your connection string, and that will be what shows up in the profiler.

Related

Exporting azure database in powershell with New-AzSqlDatabaseExport does not always return the OperationStatusLink, resulting in an exception

I am writing a powershell script to export an Azure database to a bacpac file using the New-AzSqlDatabaseExport command (following the documentation here.
When I run the powershell script, the results I get are inconsistent. When I open a new powershell window and run the export database script, everything runs as expected, and I get back an OperationStatusLink, so I can check the progress of the export as it progresses. However, once the export completes, if I try running the powershell script a 2nd time within the same window, the export will not return the OperationStatusLink. This will cause Get-AzSqlDatabaseImportExportStatus to fail with the following exception: Cannot bind argument to parameter 'OperationStatusLink' because it is null.
Below are the steps to reproduce, as well as a snippet of powershell script. Any suggestions as to what I could possibly try to ensure that New-AzSqlDatabaseExport always returns an OperationStatusLink would be greatly appreciated.
Steps to Reproduce:
Open powershell window
Log in to Azure
Run script to export database to bacpac
Expected Result: Export is successful and OperationStatusLink is provided
Actual Result: Export is successful and OperationStatusLink is provided
Run script to export database to bacpac
Expected Result: Export is successful and OperationStatusLink is provided
Actual Result: Export is successful and OperationStatusLink is not provided
Powershell script:
Connect-AzAccount
Select-AzSubscription -SubscriptionName 'subscription name'
BackupAzureDatabase.ps1 `
-DatabaseName "testDB" `
-ResourceGroupName "group1" `
-ServerName "testserver" `
-serverAdmin "admin" `
-serverPassword "********" `
BackupAzureDatabase.ps1:
Param(
[string][Parameter(Mandatory=$true)] $DatabaseName,
[string][Parameter(Mandatory=$true)] $ResourceGroupName,
[string][Parameter(Mandatory=$true)] $ServerName,
[string][Parameter(Mandatory=$true)] $ServerAdmin,
[string][Parameter(Mandatory=$true)] $ServerPassword,
)
Process{
# some code to get the storage info and credentials
$ExportRequest = New-AzSqlDatabaseExport `
-ResourceGroupName $ResourceGroupName `
-ServerName $ServerName `
-DatabaseName $DatabaseName `
-StorageKeytype $StorageKeytype `
-StorageKey $PrimaryKey `
-StorageUri $BacpacUri `
-AdministratorLogin $Creds.UserName `
-AdministratorLoginPassword $Creds.Password
$ExportStatus = Get-AzSqlDatabaseImportExportStatus `
-OperationStatusLink $ExportRequest.OperationStatusLink
# Get-AzSqlDatabaseImportExportStatus throws an exception, since OperationStatusLink is empty/null most of the time
}
This seems to be a regression in Az.Sql module introduced in 2.10.0 and it still active with the current version (2.11.0)
Symptoms:
when initiating export operation the following exception raised: New-AzSqlDatabaseExport: Missing the required 'networkIsolation' parameters for ImportExport operation.
The issue:
this should be optional parameter, and the parameter name is incorrect, it should be -UseNetworkIsolation instead.
Workaround:
target your script to older version of the module, 2.9.1 seems to be OK.
Long term solution:
The fix already committed, it should be available in the next releases on the module.
Source of information:
https://github.com/Azure/azure-powershell/issues/13097
Update 2020-11-04
The recent version of the module already contains the fix.
(2.11.1)
https://www.powershellgallery.com/packages/Az/5.0.0

Using PowerShell DataTable to import data into SQL Server table

I need to import a .csv file with 350 columns into a SQL Server 2008 R2 database.
Surfing the internet I came up with a function called Out-DataTable from Chad Miller: link to script on Technet
I have used this to complete the PowerShell script as follows:
#----------------------------------------------------------------
$logNaam=MylogFileName
TRY
{
$ConnectionString = "Data Source=mySQLServer; Initial Catalog=MyDB; Trusted_Connection=True;";
. ".\Out-DataTable.ps1"
$csvDataTable = Import-CSV -Path "MyCSV_FileAndPath" | Out-DataTable
$bulkCopy = new-object ("Data.SqlClient.SqlBulkCopy") $ConnectionString
$bulkCopy.DestinationTableName = "to_MyTableName"
$bulkCopy.WriteToServer($csvDataTable)
}
Catch
{
$ErrorMessage = $_.Exception.Message
$FailedItem = $_.Exception.ItemName
"Error: Job starten lukt niet : ($ErrorMessage) " | out-file $logNaam -append
"Error: Job starten lukt niet : ($FailedItem) " | out-file $logNaam -append
}
Finally
{}
#----------------------------------------------------------------
Running this code in the PowerShell command prompt, I get this error:
Unexpected token 'data' in expression or statement.
At .\MyScript.ps1:20 char:27
+ $ConnectionString = "Data <<<< Source=MySQLServer; Initial Catalog=MyDB
; Trusted_Connection=True;";
+ CategoryInfo : ParserError: (data:String) [], ParseException
+ FullyQualifiedErrorId : UnexpectedToken
I'm stuck with this and have no clue where to start. Changing Data Source=MySQLServer to Server=MySQLServer does not solve it. The message only changed pointing to the position following MySQLServer<<<.
Also adding the Windows server-name to it (MyWinServer\MySQLServer) did not help, either.
Any advise, directions, explanation or help to code this script would by much appreciated.

How to run a scheduled task to stop and start SSRS service with elevated permissions?

I have this SSRS latency issues on my site. So I have googled it and found out that it is the common issues for so many people. Here it is:
I have created a powershell script as follows:
Stop-Service "SQL Server Reporting Services (MSSQLSERVER)"
Start-Service "SQL Server Reporting Services (MSSQLSERVER)"
$wc = New-Object system.net.webClient
$cred = [System.Net.CredentialCache]::DefaultNetworkCredentials
$wc.Credentials = $cred
$src = $wc.DownloadString("http://example.com/Reports/Pages/Folder.aspx")
When i run this script from poweshell cmd it is throwing me an error says cannot open/access sql report server service. It seems like permissions issue. Then I came with this online solution, which invokes/elevates admin permissions to run the script to that perticular user.
function Invoke-Admin() {
param ( [string]$program = $(throw "Please specify a program" ),
[string]$argumentString = "",
[switch]$waitForExit )
$psi = new-object "Diagnostics.ProcessStartInfo"
$psi.FileName = $program
$psi.Arguments = $argumentString
$psi.Verb = "runas"
$proc = [Diagnostics.Process]::Start($psi)
if ( $waitForExit ) {
$proc.WaitForExit();
}
}
But I dont know how to run this function before running that script. Please suggest. I have added this function also to the same script file and added function-Admin() call at the top of the script to to execute this function before running the script as follows:
function-Admin()
Stop-Service "SQL Server Reporting Services (MSSQLSERVER)"
Start-Service "SQL Server Reporting Services (MSSQLSERVER)"
$wc = New-Object system.net.webClient
$cred = [System.Net.CredentialCache]::DefaultNetworkCredentials
$wc.Credentials = $cred
$src = $wc.DownloadString("http://example.com/Reports/Pages/Folder.aspx")
But is throwing following error:
Please specify a program
At C:\SSRS_Script\SSRSScript.ps1:3 char:39
+ param ( [string]$program = $(throw <<<< "Please specify a program" ),
+ CategoryInfo : OperationStopped: (Please specify a program:String) [], RuntimeException
+ FullyQualifiedErrorId : Please specify a program
You are getting that error because the function Invoke-Admin() was designed to have parameters passed for the program you wanted to run with elevated privledges. If you want your powershell script SSRSScript.ps1 to use this Invoke-Admin() you could convert it to a standalone script.
Take the code without the function declartion and outer brackets. Save this a file called Invoke-Admin.ps1
param ( [string]$program = $(throw "Please specify a program" ),
[string]$argumentString = "",
[switch]$waitForExit )
$psi = new-object "Diagnostics.ProcessStartInfo"
$psi.FileName = $program
$psi.Arguments = $argumentString
$psi.Verb = "runas"
$proc = [Diagnostics.Process]::Start($psi)
if ( $waitForExit ) {
$proc.WaitForExit();
}
With that created then you could try to elevate your script with the following:
C:\*pathtoscript*\Invoke-Admin.ps1 -program "Powershell.exe" -argumentString "-file C:\SSRS_Script\SSRSScript.ps1"
You should get the elevation prompt at that point and then, once accepted, will run another window with your script using admin rights.
This is by no means the only way to accomplish this goal.
Scheduler
You have this in the title but dont really cover it in the question. Running this as a scheduled task will not work since it requires user input. You could however just make a task with your script as is assuming it works unattended.
General Tab
Run whether user is logged on or not
Run with highest privileges
Action > New...
Action: Start a program Program/script: %SystemRoot%\system32\WindowsPowerShell\v1.0\powershell.exe
Add arguments: -ExecutionPolicy Unrestricted -NoProfile -File C:\SSRS_Script\SSRSScript.ps1
Start in (optional): %SystemRoot%\system32\WindowsPowerShell\v1.0

CakePHP 2.2 AclExtras aco_sync in browser (sh permission denied)

I'm working on a remote server and I can't use the console because ssh is not enabled. So I need to run aco_sync directly from the browser (or any other way that doesn't involve the shell).
I managed to sync acos on my local dev server with the following code in controller/action:
$command = ROOT . DS . APP_DIR . DS . 'Console' . DS . 'cake';
$params = ' -app ' . ROOT . DS . APP_DIR;
$params .= ' AclExtras.AclExtras';
$params .= ' aco_sync';
$result = shell_exec($command . $params);
But on the production server (with cPanel) I just get no response for about 5 minutes and then I get an internal server error (500). I simply hangs. Actually, this happened on two different VPS servers with cPanel. In the first one, I had ssh and was able to run the command from the console. But when running the quoted code from the browser, I hung just as the other server.
I found no logged errors either on php log files nor cake's log files.
The action is prefixed with "admin_" and ACL doesn't allow execution if not logged in.
'./cake' script file has execute permissions (took me a while to figure this was necessary).
I tried on Chrome and IE8.
Debug level was set to 1.
After trying to run the script, the page broke and I wasn't able to browse until I opened an incognito window or restarted the browser.
I think the server's memory gets completely consumed when I run this script. I've had to restart httpd to get the site up and running again on the server that I could control.
I've seen some implementations using $dispatcher->dispatch() and tried a bunch of them but with no luck.
Any ideas?
App::uses('ShellDispatcher', 'Console');
$command = '-app '.APP.' AclExtras.AclExtras aco_sync';
$args = explode(' ', $command);
$dispatcher = new ShellDispatcher($args, false);
if($dispatcher->dispatch()) {
echo 'OK';
} else {
echo 'Error';
}
Try this, the $dispatcher->dispatch(); seems to show something only in case of an error.
run this and check your database.
App::uses('ShellDispatcher', 'Console');
$command = '-app '.APP.' AclExtras.AclExtras aco_sync';
$args = explode(' ', $command);
$dispatcher = new ShellDispatcher($args, false);
try {
$dispatcher->dispatch();
} catch (Exception $e) {
pr($e);
}

Invoke-SqlCmd QueryTimeout

Does anyone know how to set Invoke-SqlCmd QueryTimeout more than 65535?
Microsoft said that they have fixed it in Denali but we are still using SQL 2008 R2 with latest service packs.
http://connect.microsoft.com/SQLServer/feedback/details/551799/invoke-sqlcmd-querytimeout-0-still-times-out
Basically, we are trying to backup or restore the database using powershell. Some of our databases are very large so it takes more than 65535 to complete the job.
Some suggested that we should use ADO.NET with timeout in powershell. But I wonder if we have any workaround for Invoke-SqlCmd...
Invoke-Sqlcmd -query 'select * from largeDb' -QueryTimeout 0
-QueryTimeout 0 : will make your cmdlet from timing out.
AFAIK By soon, this bug will be resolved.
You can use the below function to customize your own Query time out and session time out limits (while defining the parameters you can give you own desired values)
function Invoke-SqlCommand
{
[CmdletBinding()]
param(
[Parameter(Position=0, Mandatory=$true)] [string]$ServerInstance,
[Parameter(Position=1, Mandatory=$false)] [string]$Database,
[Parameter(Position=2, Mandatory=$false)] [string]$Query,
[Parameter(Position=3, Mandatory=$false)] [string]$Username,
[Parameter(Position=4, Mandatory=$false)] [string]$Password,
[Parameter(Position=5, Mandatory=$false)] [Int32]$QueryTimeout=600,
[Parameter(Position=6, Mandatory=$false)] [Int32]$ConnectionTimeout=15,
[Parameter(Position=7, Mandatory=$false)] [ValidateScript({test-path $_})] [string]$InputFile,
[Parameter(Position=8, Mandatory=$false)] [ValidateSet("DataSet", "DataTable", "DataRow")] [string]$As="DataRow"
)
if ($InputFile)
{
$filePath = $(resolve-path $InputFile).path
$Query = [System.IO.File]::ReadAllText("$filePath")
}
$conn=new-object System.Data.SqlClient.SQLConnection
if ($Username)
{ $ConnectionString = "Server={0};Database={1};User ID={2};Password={3};Trusted_Connection=False;Connect Timeout={4}" -f $ServerInstance,$Database,$Username,$Password,$ConnectionTimeout }
else
{ $ConnectionString = "Server={0};Database={1};Integrated Security=True;Connect Timeout={2}" -f $ServerInstance,$Database,$ConnectionTimeout }
$conn.ConnectionString=$ConnectionString
#Following EventHandler is used for PRINT and RAISERROR T-SQL statements. Executed when -Verbose parameter specified by caller
if ($PSBoundParameters.Verbose)
{
$conn.FireInfoMessageEventOnUserErrors=$true
$handler = [System.Data.SqlClient.SqlInfoMessageEventHandler] {Write-Verbose "$($_)"}
$conn.add_InfoMessage($handler)
}
$conn.Open()
$cmd=new-object system.Data.SqlClient.SqlCommand($Query,$conn)
$cmd.CommandTimeout=$QueryTimeout
$ds=New-Object system.Data.DataSet
$da=New-Object system.Data.SqlClient.SqlDataAdapter($cmd)
[void]$da.fill($ds)
$conn.Close()
switch ($As)
{
'DataSet' { Write-Output ($ds) }
'DataTable' { Write-Output ($ds.Tables) }
'DataRow' { Write-Output ($ds.Tables[0]) }
}
}
Hope it HElps.
You can write your own version of Invoke-SqlCmd that directly uses the System.Data.SqlClient object and do anything that you want to with it. There are a bunch of examples of how to do this to be found, including invoke-sqlcmd2, which was specifically written to get around the QueryTimeout bug and is hosted on Microsoft's scripting gallery. If you don't want to deploy such a script, you can just integrate the relevant code directly into your backup script.
Alternatively, you should be able to use SMO to backup the database. IIRC, the querytimeout bug does not affect SMO.

Resources