Quantcast
Channel: SQL Server Blog : sql
Viewing all 552 articles
Browse latest View live

Some Pester Tests for SQL Defaults

$
0
0

When I was at PowerShell Conference EU in Hannover last month (The videos are available now – click here and the slides and code here) I found out about Irwin Strachans Active Directory Operations Test which got me thinking.

I decided to do the same for my usual SQL Set-up. Treating all of your servers to the same defaults makes it even easier to manage at scale remotely.

I am comfortable with using SMO to gather and change properties on SQL Instances so I started by doing this

        It 'Should have a default Backup Directory of F:\SQLBACKUP\BACKUPS' {
$Scriptblock = {
[void][reflection.assembly]::LoadWithPartialName('Microsoft.SqlServer.Smo');
$srv = New-Object Microsoft.SqlServer.Management.Smo.Server .
return $srv.BackupDirectory}
$State = Invoke-Command -ComputerName ROB-SURFACEBOOK -ScriptBlock $Scriptblock
$State |Should Be 'F:\SQLBACKUP\BACKUPS'

This is the how to find the properties that you want

  ## Load the Assemblies
[void][reflection.assembly]::LoadWithPartialName('Microsoft.SqlServer.Smo');
## Create a Server SMO object
$srv = New-Object Microsoft.SqlServer.Management.Smo.Server SERVERNAME

## Explore it
$srv|gm

## If you find an array pick the first one and expand and then explore that
$srv.Databases[0] | select *
$srv.Databases[0] | gm

I quickly found as I added more tests that it was taking a long time to perform the tests (about 5 seconds each test) and that it took an age to fail each of the tests if the server name was incorrect or the server unavailable.

I fixed the first one by testing with a ping before running the tests

   ## Check for connectivity
if((Test-Connection $Server -count 1 -Quiet) -eq $false){
Write-Error 'Could not connect to $Server'
$_
continue
}

The continue is there because I wanted to loop through an array of servers

I improved the performance using a remote session and a custom object

      Describe "$Server" {
BeforeAll {
$Scriptblock = {
[pscustomobject]$Return = @{}
$srv = ''
$SQLAdmins = $Using:SQLAdmins
[void][reflection.assembly]::LoadWithPartialName('Microsoft.SqlServer.Smo');
$srv = New-Object Microsoft.SQLServer.Management.SMO.Server $Server
$Return.DBAAdminDb = $Srv.Databases.Name.Contains('DBA-Admin')
$Logins = $srv.Logins.Where{$_.IsSystemObject -eq $false}.Name
$Return.SQLAdmins = @(Compare-Object $Logins $SQLAdmins -SyncWindow 0).Length - $Logins.count -eq $SQLAdmins.Count
$SysAdmins = $Srv.Roles['sysadmin'].EnumMemberNames()
$Return.SQLAdmin = @(Compare-Object $SysAdmins $SQLAdmins -SyncWindow 0).Length - $SysAdmins.count -eq $SQLAdmins.Count
$Return.BackupDirectory = $srv.BackupDirectory
$Return.DataDirectory = $srv.DefaultFile

The BeforeAll script block is run, as it sounds like it should, once before all of the tests, BeforeEach would run once before each of the tests. I define an empty custom object and then create an SMO object and add the properties I am interested in testing to it. I then return the custom object at the end

   $Return.Alerts82345Exist = ($srv.JobServer.Alerts |Where {$_.Messageid -eq 823 -or $_.Messageid -eq 824 -or $_.Messageid -eq 825}).Count
$Return.Alerts82345Enabled = ($srv.JobServer.Alerts |Where {$_.Messageid -eq 823 -or $_.Messageid -eq 824 -or $_.Messageid -eq 825 -and $_.IsEnabled -eq $true}).Count
$Return.SysDatabasesFullBackupToday = $srv.Databases.Where{$_.IsSystemObject -eq $true -and $_.Name -ne 'tempdb' -and $_.LastBackupDate -lt (Get-Date).AddDays(-1)}.Count
Return $Return
}
try {
$Return = Invoke-Command -ScriptBlock $Scriptblock -ComputerName $Server -ErrorAction Stop
}
catch {
Write-Error "Unable to Connect to $Server"
$Error
continue

I was then able to test against the property of the custom object

   It 'Should have Alerts for Severity 20 and above' {
$Return.Alerts20SeverityPlusExist | Should Be 6
}
It 'Severity 20 and above Alerts should be enabled' {
$Return.Alerts20SeverityPlusEnabled | Should Be 6
}
It 'Should have alerts for 823,824 and 825' {
$Return.Alerts82345Exist |Should Be 3
}
It 'Alerts for 823,824 and 825 should be enebled' {
$Return.Alerts82345Enabled |Should Be 3
}

Occasionally, for reasons I haven’t explored I had to test against the value property of the returned object

          It "The Full User Database Backup should be scheduled Weekly $OlaUserFullSchedule" {
$Return.OlaUserFullSchedule.value | Should Be $OlaUserFullSchedule
}

I wanted to be able to run the tests against environments or groups of servers with different default values so I parameterised the Test Results as well and then the logical step was to turn it into a function and then I could do some parameter splatting. This also gives me the opportunity to show all of the things that I am currently giving parameters to the test for

   $Parms = @{
Servers = 'SQLServer1','SQLServer2','SQLServer3';
SQLAdmins = 'THEBEARD\Rob','THEBEARD\SQLDBAsAlsoWithBeards';
BackupDirectory = 'C:\MSSQL\Backup';
DataDirectory = 'C:\MSSQL\Data\';
LogDirectory = 'C:\MSSQL\Logs\';
MaxMemMb = '4096';
Collation = 'Latin1_General_CI_AS';
TempFiles = 4 ;
OlaSysFullFrequency = 'Daily';
OlaSysFullStartTime = '21:00:00';
OlaUserFullSchedule = 'Weekly';
OlaUserFullFrequency = 1 ;## 1 for Sunday
OlaUserFullStartTime = '22:00:00';
OlaUserDiffSchedule = 'Weekly';
OlaUserDiffFrequency = 126; ## 126 for every day except Sunday
OlaUserDiffStartTime = '22:00:00';
OlaUserLogSubDayInterval = 15;
OlaUserLoginterval = 'Minute';
HasSPBlitz = $true;
HasSPBlitzCache = $True;
HasSPBlitzIndex = $True;
HasSPAskBrent = $true;
HASSPBlitzTrace =  $true;
HasSPWhoisActive = $true;
LogWhoIsActiveToTable = $true;
LogSPBlitzToTable = $true;
LogSPBlitzToTableEnabled = $true;
LogSPBlitzToTableScheduled = $true;
LogSPBlitzToTableSchedule = 'Weekly';
LogSPBlitzToTableFrequency = 2 ; # 2 means Monday
LogSPBlitzToTableStartTime  = '03:00:00'}

Test-SQLDefault @Parms

I have some other tests which always return what I want, particularly the firewall rules which you will have to modify to suit your own environment

To be able to runt this you will need to have the Pester Module. If you are using Windows 10 then it is installed by default, if not

  Find-Module –Name 'Pester' | Install-Module

You can find more about Pester here and here and also these videos from the conference
You can find the tests on GitHub here and I will continue to add to the defaults that I check.
This is not a replacement for other SQL configuration tools such as PBM but it is a nice simple way of giving a report on the current status of a SQL installation either at a particular point in time when something is wrong or after an installation prior to passing the server over to another team or into service

.



Do You Even Blog Bro? (Stats, Execution Plans, Indexes, and crazyness)

$
0
0

Have you ever worked with a piece of software for like 15-20 years and ended up doing something with that product that you haven’t or can’t remember doing ever before?

joygasm

 

This happened to me quite recently and although I wont have a bunch of sexy scripts for you to reproduce the problem I will go through what I learned/remembered you can do with statistics.

Scenario:

  • Production database at a customer site is choosing an absolutely shitty execution plan (not using an index as expected).
  • Can’t get a backup
  • Don’t want to “cowboy” it up on a live 24/7 $$$$$$ production system
  • Can’t reproduce in development with an old backup that we have on site.

SadPanda

Trying to determine “why” this is happening was proving to be a rat-hole until I came across this:

http://blog.kejser.org/the-ascending-column-problem-in-fact-tables-part-two-stat-job/

specifically the part that said showed that you can run this:


DBCC SHOW_STATISTICS ([TableName], [StatisticsName]) WITH STATS_STREAM

What this UNDOCUMENTED/UNSUPPORTED/BE VERY CAREFUL USING/GREAT POWER BLAH BLAH BLAH is doing is this is actually scripting out your statistics and the histogram

dsjkfjdsoks

 

Now that you have the statistics from (in my case) the production database that I cannot get a backup of, or actively troubleshoot against, etc I can then run the following statement on my development server (which has an older backup of the database in question restored)


UPDATE STATISTICS [dbo].[TableName]([StatisticName]) WITH STATS_STREAM = 0x01000000010000000000000000000000B242E5900000000000038......etc., ROWCOUNT = 159543018, PAGECOUNT = 2904894
GO

And BOOM… we were able to reproduce and establish the root-cause of the issue.

After googling around for blog posts about STATS_STREAM I did find the following as well:

Anyways this was just one of those moments where I got all excited and had that awesome feeling about trying something new and having it work.

Now that SQL Server 2016 is available to download for everyone I imagine I’ll have more “a-ha” moments

Aha

(If you don’t get the reference you’re young and I hate you and get off my lawn!!!)

Thanks!!

Enjoy!! (Follow me on Twitter: @ColinStasiuk)

Post to TwitterPost to DeliciousPost to DiggPost to StumbleUpon

Strategically Fix SQL Server Error 15118 – Password Validation Failed

$
0
0

Problem

While working on SQL Server database sometimes users may get the following error message.

Password validation failed. The password does not meet the windows policy requirements because it not complex enough (MS SQL Server Error 15118)

The password’s character-length is more than required but it does not contain any special characters.

Solution

Users can easily resolve the issue of resetting the SQL Server password through common fixes. There are two possible ways to overcome the SQL Server Error 15118, i.e.

  • By using SQL Server Management studio and T-SQL
  • By using CMD

Both the mentioned ways, involve some steps to reset the password and resolve the occurrence of password validation failed error 15118.

By Using SQL Server Management Studio and T-SQL

  • Enabling the SA Account

User can reset the password by changing the SQL Server Authentication Mode from Windows to SQL Server and Windows Authentication mode, which is known as Mixed Mode Authentication. Select SA account as SQL Server logon account and enable SA account with two ways as discussed:

  • Using SQL Server Management Studio
    1. Once the SQL Server Mixed Authentication mode is enabled, navigate to the security option.
    2. Then, go to Login Option>> Object Explorer>> Enable SA Account.
    3. Now, right-click on SA Account>>Login Properties>> set password for SA Account>> Confirm.
    4. Choose an option Status>> Set SA Account>> Enable>>click Ok.
    5. Close the login properties.
  • Using T-SQL
    1. Login to SQL Server by using open Management Studio and Windows Authentication mode.
    2. Now to create a query click on New Query and type a query:

    password validation failed sql server 2008 error 15118

  • By executing the commands in query, SA account will be enabled and easily set SQL Server logon

NOTE: Once the process has completed, restart the SQL Server Services and under SQL Server Authentication mode, user will be able to login to SQL Server with SA account.

  • Password Confirmation

Once the SQL Authentication is changed, user needs to restart the Server to check for the changes, which has taken place. After that go to General>> Password>> Confirm-Password>> click OK.

By Using CMD

There is another way to disable the password complexity requirement, i.e. by simply following the steps given:

  • Run command prompt as Administrator>> type:

code-2

  • Run Notepad, and open local.cfg to edit>> change the “PasswordComplexity=1”, change 1 to 0
  • User can also set the maximum length requirements higher or lower with “MinimumPasswordLength” key >> close notepad before saving.
  • Now at command prompt, type

code-3

  • Re-launch “Local Security Policy” window and refresh its value.
  • After this, user can set less secure as well as less complex password.

      Limitation: By using the CMD, user sometimes faces an error, i.e.

      code-4

      Solution: The limitation can be overcome by adding any user to systemadmin role and after that user can make the use of same name to modify the system admin’s tool to fix the issue.

      Conclusion

      In the above blog, we have discussed two-ways to resolve the occurrence of SQL Server error 15118 password validation failed. In first solution, there are sub-parts, which help to resolve the error occurrence. Whereas, in second solution, there is a bit of complications as well as users may sometimes face an error after implementing the process. However, the possible workaround to solve the issue has also been discussed for users who may face SQL Server Error 15118.There may be some other password failure situations like SQL Server Error 18456 that generally occurs while user connecting to the database.


    How To Make Bootable USB

    $
    0
    0

    Last month, in my effort to show support to Tim Ford (Blog | Twitter) efforts #iwanttoshare so, I wrote this article about HOW TO: Use ROBOCOPY to Move SQL Files. (Background: asked for fellow bloggers to write about entry level topics. He stated that from time to time he gets feedback that people reading our blogs do not always understand some of the assumptions that we presume our readers may know. In some cases, we tend to try and outshine one another to demonstrate our knowledge, experience or passion in our topics that leaves many readers lost)

    This month’s topic is about creating a bootable USB, which is essential to installing an operating system (OS) since it is not only makes the installation faster, but also saves time trying to find a DVD disc or burner! (Rather rare to see now a days) About 5 years or so ago, Microsoft created a very handy tool called Windows 7 USB/DVD Download Tool to help with burning an ISO image to either a USB or DVD drive. However, as time has progressed it is not as helpful with Windows 8 or newer operating systems. The bad news is that newer operating systems now allow you to mount ISO images and the Windows 7 download tool does not work correctly today. The good news is that creating or using a USB drive to install Windows operating systems is a very easy task, if you follow the steps below, Also, these steps will work on Vista, Windows 7, Windows 8/8.1, or Windows 10.

    Insert your USB (4GB+ preferable) stick to the system and backup all the data from the USB as we are going to format the USB to make it as bootable. Open elevated Command Prompt. To do this, type in CMD in Start menu search field and hit Ctrl + Shift + Enter. Alternatively, navigate to Start > All programs >Accessories > right click on Command Prompt and select run as administrator. (You can also use the Windows Key + X)

    When the Command Prompt opens, enter the following commands:

    • diskpart
    • list disk

    Once you enter the LIST DISK command, it will show the disk number of your USB drive. (Normally it is one of the last numbers, since it comes up after FIXED drives)

    • select disk x

    Replace the x with your disk number, in my case it was disk 2 and then enter the following commands:

    • clean
    • create partition primary
    • select partition 1
    • active
    • format FS=FAT32 label=WIN10_US quick

    Note: If you are not using the quick command, then the format will take considerably more time

    • assign letter=Z
    • exit

    Don’t close the command prompt as we need to execute one more command at the next step. Just minimize it. Insert your Windows DVD in the optical drive and note down the drive letter of the optical drive and USB media. Here I use “D” as my optical (DVD) drive letter and “Z” as my USB drive letter.

    • bootsect /nt60 Z:

    Copy the contents from the Windows DVD to USB drive.

    • xcopy Z:\*.* D:\ /E /F /H

    At this point, you are done with creating a bootable USB drive. You can now use this bootable USB in the same manner as a bootable DVD to install an operating system. As usual, I hope this helps you and allows you to install operating systems without needing to purchase or download a third party program.

    Here is all the code in one setting:

    diskpart
    list disk
    select disk 2
    clean
    create partition primary
    select partition 1
    active
    format FS=FAT32 label=WIN10_US quick
    assign letter=Z
    exit
    bootsect /nt60 Z:
    xcopy D:\*.* Z:\ /E /F /H

    PowerShell CMDLets added for SQL2016 Always Encrypted

    $
    0
    0

    The post on the SQLServer blog at TechNet by the SQL Server Tools Team today made me jump out of my seat.

    The July update for SSMS includes the first substantial improvement in SQL PowerShell in many years. We owe a lot of thanks for this effort to the great collaboration with our community. We have several new CMDLETs to share with you

    In one release there are twenty-five new CMDLets for the new sqlserver module

    This means that if you have a PowerShell script doing Import-Module SQLPS, it will need to be changed to be Import-Module SqlServer in order to take advantage of the new provider functionality and new CMDLETs. The new module will be installed to “%Program Files\WindowsPowerShell\Modules\SqlServer” and hence no update to $env:PSModulePath is required.

    So SQLPS will still continue to work but will not be updated and will not contain the new CMDlets or the future new CMDlets.

    So what new things do we have?

    This month we introduce CMDLETs for the following areas:

    • Always Encrypted
    • SQL Agent
    • SQL Error Logs

    Chrissy LeMaire has written about the new SQL Agent cmdlets

    Aaron Nelson has written about the new Get-SqlErrorLog cmdlet

    Laerte Junior has written about Invoke-SQLCmd

    All four of us will be presenting a webinar on the new CMDlets via the PowerShell Virtual Chapter Wed, Jul 06 2016 12:00 Eastern Daylight Time If you cant make it a recording will be made available on YouTube on the VC Channel https://sqlps.io/video

    Always Encrypted CMDlets

    That leaves the Always Encrypted CMDLets and there are 17 of those!

    Add-SqlColumnEncryptionKeyValueAdds a new encrypted value for an existing column encryption key object in the database.
    Complete-SqlColumnMasterKeyRotationCompletes the rotation of a column master key.
    Get-SqlColumnEncryptionKeyReturns all column encryption key objects defined in the database, or returns one column encryption key object with the specified name.
    Get-SqlColumnMasterKeyReturns the column master key objects defined in the database, or returns one column master key object with the specified name.
    Invoke-SqlColumnMasterKeyRotationInitiates the rotation of a column master key.
    New-SqlAzureKeyVaultColumnMasterKeySettingsCreates a SqlColumnMasterKeySettings object describing an asymmetric key stored in Azure Key Vault.
    New-SqlCngColumnMasterKeySettingsCreates a SqlColumnMasterKeySettings object describing an asymmetric key stored in a key store supporting the Cryptography Next Generation (CNG) API.
    New-SqlColumnEncryptionKeyCrates a new column encryption key object in the database.
    New-SqlColumnEncryptionKeyEncryptedValueProduces an encrypted value of a column encryption key.
    New-SqlColumnEncryptionSettingsCreates a new SqlColumnEncryptionSettings object that encapsulates information about a single column’s encryption, including CEK and encryption type.
    New-SqlColumnMasterKeyCreates a new column master key object in the database.
    New-SqlCspColumnMasterKeySettingsCreates a SqlColumnMasterKeySettings object describing an asymmetric key stored in a key store with a Cryptography Service Provider (CSP) supporting Cryptography API (CAPI).
    Remove-SqlColumnEncryptionKeyRemoves the column encryption key object from the database.
    Remove-SqlColumnEncryptionKeyValueRemoves an encrypted value from an existing column encryption key object in the database.
    Remove-SqlColumnMasterKeyRemoves the column master key object from the database.
    Set-SqlColumnEncryptionEncrypts, decrypts or re-encrypts specified columns in the database.
     

     

    That seems to cover setting up Always Encrypted with Powershell , removing it and getting information about it. When the new SSMS update is dropped you will be able to start using all of this new functionality.

    Just remember Import-Module sqlserver

    CALL TO ACTION

    Microsoft are engaging with the community to improve the tools we all use in our day to day work. There is are two Trello boards set up for YOU to use to contribute

    https://sqlps.io/vote  for SQLPS  sqlserver PowerShell module

    https://sqlps.io/ssms for SSMS

    Go and join them and upvote YOUR preferred choice of the next lot of CMDlets

    trellocount

     

    We have also set up a SQL Community Slack for anyone in the community to discuss all things related to SQL including the Trello board items and already it seems a good place for people to get help with 150+ members in a few days. You can get an invite here https://sqlps.io/slack

    Come and join us


    Using the new SQLServer Powershell module to get SQL Agent Job Information

    $
    0
    0

    So with the July Release of SSMS everything changed for using PowerShell with SQL. You can read the details here As I mentioned in my previous post the name of the module has changed to sqlserver

    This means that if you have a PowerShell script doing Import-Module SQLPS, it will need to be changed to be Import-Module SqlServer in order to take advantage of the new provider functionality and new CMDLETs. The new module will be installed to “%Program Files\WindowsPowerShell\Modules\SqlServer” and hence no update to $env:PSModulePath is required.

    You can download the latest SSMS release here Once you have installed and rebooted you can start to look at the new Powershell CMDlets

     Import-module sqlserver

    Take a look at cmdlets

     Get-command -module sqlserver

    Today I want to look at agent jobs

     Get-command *sqlagent*

    getcomand sqlagent

    So I decided to see how to gather the information I gather for the DBADatabase as described here

    This is the query I use to insert the data for the server level agent job information.

     $Query = @"
    INSERT INTO [Info].[AgentJobServer]
     ([Date]
     ,[InstanceID]
     ,[NumberOfJobs]
     ,[SuccessfulJobs]
     ,[FailedJobs]
     ,[DisabledJobs]
     ,[UnknownJobs])
     VALUES
     (GetDate()
     ,(SELECT [InstanceID]
    FROM [DBADatabase].[dbo].[InstanceList]
    WHERE [ServerName] = '$ServerName'
    AND [InstanceName] = '$InstanceName'
    AND [Port] = '$Port')
     ,'$JobCount'
     ,'$successCount'
     ,'$failedCount'
     ,'$JobsDisabled'
     ,'$UnknownCount')
    "@

    So Get-SQLAgentJob looks like the one I need. Lets take a look at the help. This should be the starting point whenever you use a new cmdlet

     Get-Help Get-SqlAgentJob -Full

    Which states

    Returns a SQL Agent Job object for each job that is present in the target instance of SQL Agent.

    That sounds like it will meet my needs. Lets take a look

    Get-SqlAgentJob -ServerInstance $Connection|ft -AutoSize

    sqlinstances

    I can get the information I require like this

    
    $JobCount = (Get-SqlAgentJob -ServerInstance $Connection ).Count
    $successCount = (Get-SqlAgentJob -ServerInstance $Connection ).where{$_.LastRunOutcome -eq 'Succeeded'}.Count
    $failedCount = (Get-SqlAgentJob -ServerInstance $Connection ).where{$_.LastRunOutcome -eq 'Failed'}.Count
    $JobsDisabled = (Get-SqlAgentJob -ServerInstance $Connection ).where{$_.IsEnabled -eq $false}.Count
    $UnknownCount = (Get-SqlAgentJob -ServerInstance $Connection ).where{$_.LastRunOutcome -eq 'Unknown'}.Count

    NOTE – That code is for PowerShell V4 and V5, if you are using earlier versions of PowerShell you would need to use

    $JobCount = (Get-SqlAgentJob -ServerInstance $Connection ).Count
    $successCount = (Get-SqlAgentJob -ServerInstance $Connection|Where-Object {$_.LastRunOutcome -eq 'Succeeded'}).Count
    $failedCount = (Get-SqlAgentJob -ServerInstance $Connection |Where-Object {$_.LastRunOutcome -eq 'Failed'}).Count
    $JobsDisabled = (Get-SqlAgentJob -ServerInstance $Connection |Where-Object{$_.IsEnabled -eq $false}).Count
    $UnknownCount = (Get-SqlAgentJob -ServerInstance $Connection |Where-Object{$_.LastRunOutcome -eq 'Unknown'}).Count

    But to make the code more performant it is better to do this

     [pscustomobject]$Jobs= @{}
    $Jobs.JobCount = (Get-SqlAgentJob -ServerInstance $Connection ).Count
    $Jobs.successCount = (Get-SqlAgentJob -ServerInstance $Connection ).where{$_.LastRunOutcome -eq 'Succeeded'}.Count
    $Jobs.failedCount = (Get-SqlAgentJob -ServerInstance $Connection ).where{$_.LastRunOutcome -eq 'Failed'}.Count
    $Jobs.JobsDisabled = (Get-SqlAgentJob -ServerInstance $Connection ).where{$_.IsEnabled -eq $false}.Count
    $Jobs.UnknownCount = (Get-SqlAgentJob -ServerInstance $Connection ).where{$_.LastRunOutcome -eq 'Unknown'}.Count
    $Jobs

    jobs

    Using Measure-Command showed that this completed in
    TotalSeconds : 0.9889336
    Rather than
    TotalSeconds : 2.9045701

    Note that

     (Get-SqlAgentJob -ServerInstance $Connection ).where{$_.Enabled -eq $false}.Count

    Does not work. I had to check the properties using

     Get-SqlAgentJob -ServerInstance $Connection |Get-Member -Type Properties

    Which showed me

    IsEnabled Property bool IsEnabled {get;set;}

    So I tested this against the various SQL versions I had in my lab using this code

    $Table = $null
    $Table = New-Object System.Data.DataTable "Jobs"
    $Col1 = New-Object System.Data.DataColumn ServerName,([string])
    $Col2 = New-Object System.Data.DataColumn JobCount,([int])
    $Col3 = New-Object System.Data.DataColumn SuccessCount,([int])
    $Col4 = New-Object System.Data.DataColumn FailedCount,([int])
    $Col5 = New-Object System.Data.DataColumn DisabledCount,([int])
    $Col6 = New-Object System.Data.DataColumn UnknownCount,([int])</div>
    <div></div>
    <div>$Table.Columns.Add($Col1)
    $Table.Columns.Add($Col2)
    $Table.Columns.Add($Col3)
    $Table.Columns.Add($Col4)
    $Table.Columns.Add($Col5)
    $Table.Columns.Add($Col6)</div>
    <div></div>
    <div> foreach ($ServerName in $DemoServers)
    {
    ## $ServerName
    $InstanceName =  $ServerName|Select-Object InstanceName -ExpandProperty InstanceName
    $Port = $ServerName| Select-Object Port -ExpandProperty Port
    $ServerName = $ServerName|Select-Object ServerName -ExpandProperty ServerName
    $Connection = $ServerName + '\' + $InstanceName + ',' + $Port
    try
    {
    $srv = New-Object ('Microsoft.SqlServer.Management.Smo.Server') $Connection
    }
    catch
    {
    " Failed to connect to $Connection"
    }
    if (!( $srv.version)){
    " Failed to Connect to $Connection"
    continue
    }
    [pscustomobject]$Jobs= @{}
    $JobHistory = Get-SqlAgentJob -ServerInstance $Connection</div>
    <div></div>
    <div>$Row = $Table.NewRow()
    $Row.ServerName = $ServerName
    $Row.JobCount = $JobHistory.Count
    $Row.SuccessCount = $JobHistory.where{$_.LastRunOutcome -eq 'Succeeded'}.Count
    $Row.FailedCount = $JobHistory.where{$_.LastRunOutcome -eq 'Failed'}.Count
    $Row.DisabledCount = $JobHistory.where{$_.IsEnabled -eq $false}.Count
    $Row.UnknownCount = $JobHistory.where{$_.LastRunOutcome -eq 'Unknown'}.Count</div>
    <div></div>
    <div>$Table.Rows.Add($row)
    }
    $Table|ft
    Here are the results
    job data table

    I also had a look at Get-SQLAgentJobHistory Lets take a look at the help

    Get-help get-SQLAgentJobHistory -showwindow

    DESCRIPTION

    Returns the JobHistory present in the target instance of SQL Agent.

    This cmdlet supports the following modes of operation to return the JobHistory:

    1. By specifying the Path of the SQL Agent instance.
    2. By passing the instance of the SQL Agent in the input.
    3. By invoking the cmdlet in a valid context.

    So I ran

    Get-SqlAgentJobHistory -ServerInstance sql2014ser12r2 

    And got back a whole load of information. Every job history available on the server. Too much to look it immediately to work out what to do

    So I looked just one job

    Get-SqlAgentJobHistory -ServerInstance SQL2014Ser12R2 -JobName 'DatabaseBackup - SYSTEM_DATABASES - FULL - Local G Drive'

    And got back the last months worth of history for that one job as that is the schedule used to purge the job history for this server So then I added -Since Yesterday to only get the last 24 hours history

    Get-SqlAgentJobHistory -ServerInstance SQL2014Ser12R2 -JobName 'DatabaseBackup - SYSTEM_DATABASES - FULL - Local G Drive' -Since Yesterday

    agentjobdetail

    The Since Parameter is described as

    -Since <SinceType>

    A convenient abbreviation to avoid using the -StartRunDate parameter.
    It can be specified with the -EndRunDate parameter.

    Do not specify a -StartRunDate parameter, if you want to use it.

    Accepted values are:
    – Midnight (gets all the job history information generated after midnight)
    – Yesterday (gets all the job history information generated in the last 24 hours)
    – LastWeek (gets all the job history information generated in the last week)
    – LastMonth (gets all the job history information generated in the last month)

    When I run

    Get-SqlAgentJobHistory -ServerInstance SQL2014Ser12R2 -JobName 'DatabaseBackup - SYSTEM_DATABASES - FULL - Local G Drive' -Since Yesterday |Measure-Object

    I get

    Count : 3

    And if I run

    Get-SqlAgentJobHistory -ServerInstance SQL2014Ser12R2 -JobName 'DatabaseBackup - SYSTEM_DATABASES - FULL - Local G Drive' -Since Yesterday |select RunDate,StepID,Server,JobName,StepName,Message|Out-GridView

    I get

    agent job out gridview

    Which matches the view I see in SSMS Agent Job History

    jobhistory

    So Get-SqlAgentJobHistory will enable you to use PowerShell to gather information about the Job history for each step of the Agent Jobs and also the message which I can see being very useful.

    Come and join us in the SQL Community Slack to discuss these CMDLets and all things SQL Community https://sqlps.io/slack

    CALL TO ACTION

    Microsoft are engaging with the community to improve the tools we all use in our day to day work. There is are two Trello boards set up for YOU to use to contribute

    https://sqlps.io/vote for SQLPS sqlserver PowerShell module

    https://sqlps.io/ssms for SSMS

    Go and join them and upvote YOUR preferred choice of the next lot of CMDlets

    trellocount

    We have also set up a SQL Community Slack for anyone in the community to discuss all things related to SQL including the Trello board items and already it seems a good place for people to get help with 150+ members in a few days. You can get an invite here https://sqlps.io/slack

    Come and join us


    T-SQL Tuesday #080 – The Gift of the Basics - Syndication – WaterOx Consulting

    $
    0
    0

    This month’s T-SQL Tuesday (#080) is being hosted by Chris Yates (B|T) (Happy B-day Chris!). He decided that this month’s theme was to be a gift to the community of something you had to offer that someone else may find as a gift. Or maybe it isn’t. That’s my interpretation. You can figure it out for yourself here.   Anyhow, ...

    The post T-SQL Tuesday #080 – The Gift of the Basics appeared first on WaterOx Consulting.

    SQL – MultiServer SQL Inventory – PowerShell

    $
    0
    0

    Inventory is a vital information,whether you’re a consultant or an in-house DBA, you need to have a reliable inventory of the servers you manage.This inventory can take any number of forms but, ideally, will allow some aggregation of information. When server hardware or software changes are taking place, it’s easy to forget that the inventory has to be updated as well. For this reason, I like to have a script that creates the inventory, rather than have to keep a manual log of changes as they occur.

    It has seven parameters

    • Mandatory -InputFileName – Text File contains a list of SQL Servers – C:\Server.txt(Example)
    • Mandatory -DirectoryToSave – Folder where you want to store the file
    • Mandatory -OutputType – CSV or Excel
    • Mandatory – Email – Yes or No – If Yes, Requires below three parameter entries
    • ToID – To Email Address – One ore more recipients
    • FromID – From Email
    • SMTP – Mail Server Name

     

    Inventory_2

    Pre-requisites are –

    1. Permission to access all SQL instances
    2. Permission to create a output file
    3. You must install a SQL Server feature that includes the SQL Server PowerShell (SQLPS) module and client libraries. The easiest way to do this is by installing SQL Server Management Studio, which includes the PowerShell feature and client libraries automatically.The SQL Server PowerShell (SQLPS) module contains the PowerShell providers and cmdlets for all SQL Server features.
    4. Replication Management Objects

    The advantage of this implementation

    • Excel or CSV
    • Auto email option for one ore more recipients.
    • Console output

    Examples

    # EXAMPLE 1 :Output CSV
    
    #PS:\>.\SQLServerInventory.ps1 -InputFileName c:\server.txt -DirectoryToSaveTo 
    C:\ -OutputType 'csv' -email 'Yes' -To pram@app.com -From pram@app.com -SMTP mail.app.com  
    
    # EXAMPLE 2 :Output Excel 
    PS:\>.\SQLServerInventory.ps1 -InputFileName c:\server.txt -DirectoryToSaveTo 
    C:\ -OutputType 'excel' -email 'Yes' -To pram@app.com -From pram@app.com -SMTP mail.app.com  
    
    # EXAMPLE 3 : One or More recipients 
    PS:\>.\SQLServerInventory.ps1 -InputFileName c:\server.txt -DirectoryToSaveTo 
    C:\ -OutputType 'excel' -email 'Yes' -To "pram@app.com,pjayaram@app.vom" -From pram@app.com 
    -SMTP mail.app.com
    
    # EXAMPLE 4 :  Save the Copy under c:\
    PS:\>.\SQLServerInventory.ps1 -InputFileName c:\server.txt -DirectoryToSaveTo 
    C:\ -OutputType 'csv' -email 'No' 
    
    

    I usually recommend to generate CSV file from the server where you have loaded all sqlps modules(SMO and RMO). While generating Excel, make sure excel components are installed on the machine from which the code is being called.

    It gathers 41 very useful information such as Server Configuration(SMO),DB Count(SMO), Traceflag(EnumActiveGlobalTraceFlags()), Replication(RMO) and Mirroring, Service Account Details.

    Partial display of items in the console is due the property of FormatEnumerationLimit. The $FormatEnumerationLimit preference variable has a value of 4, and it determines how many items are displayed when a property contains more than a single item. You can set it as per your requirement. If you set it to -1 then it’s unlimited, it will display all the items.
    If you wish to display the result in the console, then select output type csv, refer EXAMPLE 2

    The traceflags items are concatenated into a single array variable. To Avoid System.Object[] (or Similar Output) using Export-Csv have used join.

    1. Name
    2. ComputerNamePhysicalNetBIOS
    3. NetName
    4. OSVer
    5. OSVersion
    6. Platform
    7. Product
    8. edition
    9. SQLServer
    10. VersionString
    11. ProductLevel
    12. DbCount
    13. HasNullSaPassword
    14. IsCaseSensitive
    15. IsFullTextInstalled
    16. Language
    17. LoginMode
    18. Processors
    19. PhysicalMemory
    20. MaxMem
    21. MinMem
    22. IsSingleUser
    23. IsClustered
    24. Collation
    25. MasterDBLogPath
    26. MasterDBPath
    27. ErrorLogPath
    28. BackupDirectory
    29. DefaultLog
    30. ResourceLastUpdateDateTime
    31. AuditLevel
    32. DefaultFile
    33. xp_cmdshell
    34. FQDN
    35. IPAddress
    36. Traceflag
    37. Replication
    38. Mirroring
    39. ServiceAccount
    40. ServiceStartMode
    41. State

     

    Code

    <#================================= 
    # Generated On: 07/18/2016 
    # Generated By: Prashanth Jayaram 
    # Version : 1.1 
    # Desc : SQL Inventory Generation 
    # EXAMPLE 1 :Output CSV#PS:\>.\SQLServerInventory.ps1 -InputFileName c:\server.txt -DirectoryToSaveTo C:\PowerSQL\ -OutputType 'csv' -email 'Yes' -To pram@app.com -From pram@app.com -SMTP mail.app.com # EXAMPLE 2 :Output ExcelPS:\>.\SQLServerInventory.ps1 -InputFileName c:\server.txt -DirectoryToSaveTo C:\ -OutputType 'excel' -email 'Yes' -To pram@app.com -From pram@app.com -SMTP mail.app.com # EXAMPLE 3 :Multiple receipientsPS:\>.\SQLServerInventory.ps1 -InputFileName c:\server.txt -DirectoryToSaveTo C:\Test\ -OutputType 'excel' -email 'Yes' -To "pram@app.com,pjayaram@app.vom" -From pram@app.com -SMTP mail.app.com # EXAMPLE 4 :No EmailPS:\>.\SQLServerInventory.ps1 -InputFileName c:\server.txt -DirectoryToSaveTo C:\123\ -OutputType 'csv' -Email 'No'
    
    
    #================================= 
    #> 
    [CmdletBinding()] 
    Param( 
     [Parameter(Mandatory=$True,Position=1)] 
     [string]$InputFileName, 
     
     [Parameter(Mandatory=$True,Position=2)] 
     [string]$DirectoryToSaveTo, 
     
     [Parameter(Mandatory=$True,Position=3)] 
     [string]$OutputType,
     
     [Parameter(Mandatory=$True,Position=4)] 
     [string]$Email,
     
     [Parameter(Position=5)] 
     [string]$To, 
     
     [Parameter(Position=6)] 
     [string]$From, 
     
     [Parameter(Position=7)] 
     [string]$SMTP 
     
    ) 
     
    $Filename='SQLInventory' 
    
    $Results = @()
     
     $a=@()
    
    # before we do anything else, are we likely to be able to save the file? 
    # if the directory doesn't exist, then create it 
    if (!(Test-Path -path "$DirectoryToSaveTo")) #create it if not existing 
     { 
     New-Item "$DirectoryToSaveTo" -type directory | out-null 
     } 
     
     If( $OutputType -eq 'Excel')
     {
     
    #Create a new Excel object using COM 
    $Excel = New-Object -ComObject Excel.Application 
    $Excel.visible = $True 
    $Excel = $Excel.Workbooks.Add() 
    $Sheet = $Excel.Worksheets.Item(1) 
     
    #Counter variable for rows 
    $intRow = 1 
    $xlOpenXMLWorkbook=[int]51 
     
    #Read thru the contents of the SQL_Servers.txt file 
    $Sheet.Cells.Item($intRow,1) ="InstanceName" 
    $Sheet.Cells.Item($intRow,2) ="ComputerNamePhysicalNetBIOS" 
    $Sheet.Cells.Item($intRow,3) ="NetName" 
    $Sheet.Cells.Item($intRow,4) ="OS" 
    $Sheet.Cells.Item($intRow,5) ="OSVersion" 
    $Sheet.Cells.Item($intRow,6) ="Platform" 
    $Sheet.Cells.Item($intRow,7) ="Product" 
    $Sheet.Cells.Item($intRow,8) ="edition" 
    $Sheet.Cells.Item($intRow,9) ="Version" 
    $Sheet.Cells.Item($intRow,10) ="VersionString" 
    $Sheet.Cells.Item($intRow,11) ="ProductLevel" 
    $Sheet.Cells.Item($intRow,12) ="DatabaseCount" 
    $Sheet.Cells.Item($intRow,13) ="HasNullSaPassword" 
    $Sheet.Cells.Item($intRow,14) ="IsCaseSensitive" 
    $Sheet.Cells.Item($intRow,15) ="IsFullTextInstalled" 
    $Sheet.Cells.Item($intRow,16) ="Language" 
    $Sheet.Cells.Item($intRow,17) ="LoginMode" 
    $Sheet.Cells.Item($intRow,18) ="Processors" 
    $Sheet.Cells.Item($intRow,19) ="PhysicalMemory" 
    $Sheet.Cells.Item($intRow,10) ="MaxMemory" 
    $Sheet.Cells.Item($intRow,21) ="MinMemory" 
    $Sheet.Cells.Item($intRow,22) ="IsSingleUser" 
    $Sheet.Cells.Item($intRow,23) ="IsClustered" 
    $Sheet.Cells.Item($intRow,24) ="Collation" 
    $Sheet.Cells.Item($intRow,25) ="MasterDBLogPath" 
    $Sheet.Cells.Item($intRow,26) ="MasterDBPath" 
    $Sheet.Cells.Item($intRow,27) ="ErrorLogPath" 
    $Sheet.Cells.Item($intRow,28) ="BackupDirectory" 
    $Sheet.Cells.Item($intRow,29) ="DefaultLog" 
    $Sheet.Cells.Item($intRow,20) ="ResourceLastUpdatetime" 
    $Sheet.Cells.Item($intRow,31) ="AuditLevel" 
    $Sheet.Cells.Item($intRow,32) ="DefaultFile" 
    $Sheet.Cells.Item($intRow,33) ="xp_cmdshell" 
    $Sheet.Cells.Item($intRow,34) ="Domain" 
    $Sheet.Cells.Item($intRow,35) ="IPAddress" 
    $Sheet.Cells.Item($intRow,36) ="TraceFlag" 
    $Sheet.Cells.Item($intRow,37) ="Mirror" 
    $Sheet.Cells.Item($intRow,38) ="Replication" 
    $Sheet.Cells.Item($intRow,39) ="ServiceAccount" 
    $Sheet.Cells.Item($intRow,40) ="ServiceStartMode" 
    $Sheet.Cells.Item($intRow,41) ="State" 
    
    
    
     
     for ($col = 1; $col –le 41; $col++) 
     { 
     $Sheet.Cells.Item($intRow,$col).Font.Bold = $True 
     $Sheet.Cells.Item($intRow,$col).Interior.ColorIndex = 48 
     $Sheet.Cells.Item($intRow,$col).Font.ColorIndex = 34 
     } 
     
    $intRow++ 
     
    foreach ($instanceName in Get-Content $InputFileName) 
    { 
    [System.Reflection.Assembly]::LoadWithPartialName('Microsoft.SqlServer.SMO') | out-null
    [System.Reflection.Assembly]::LoadWithPartialName("Microsoft.SqlServer.Replication") | out-null
    
    $server1 = New-Object -Type Microsoft.SqlServer.Management.Smo.Server -ArgumentList $instanceName 
    $rmo = New-Object Microsoft.SqlServer.Replication.ReplicationServer($instanceName) 
    $s=$server1.Information.Properties |Select Name, Value 
    $st=$server1.Settings.Properties |Select Name, Value 
    $CP=$server1.Configuration.Properties |Select DisplayName, Description, RunValue, ConfigValue 
    $dbs=$server1.Databases.count 
    $BuildNumber=$s | where {$_.name -eq "BuildNumber"}|select value 
    $edition=$s | where {$_.name -eq "edition"}|select value 
    $ErrorLogPath =$s | where {$_.name -eq "ErrorLogPath"}|select value 
    $HasNullSaPassword =$s | where {$_.name -eq "HasNullSaPassword"}|select value 
    $IsCaseSensitive =$s | where {$_.name -eq "IsCaseSensitive"}|select value 
    $Platform =$s | where {$_.name -eq "Platform"}|select value 
    $IsFullTextInstalled =$s | where {$_.name -eq "IsFullTextInstalled"}|select value 
    $Language =$s | where {$_.name -eq "Language"}|select value 
    $MasterDBLogPath =$s | where {$_.name -eq "MasterDBLogPath"}|select value 
    $MasterDBPath =$s | where {$_.name -eq "MasterDBPath"}|select value 
    $NetName =$s | where {$_.name -eq "NetName"}|select value 
    $OSVersion =$s | where {$_.name -eq "OSVersion"}|select value 
    $PhysicalMemory =$s | where {$_.name -eq "PhysicalMemory"}|select value 
    $Processors =$s | where {$_.name -eq "Processors"}|select value 
    $IsSingleUser =$s | where {$_.name -eq "IsSingleUser"}|select value 
    $Product =$s | where {$_.name -eq "Product"}|select value 
    $VersionString =$s | where {$_.name -eq "VersionString"}|select value 
    $Collation =$s | where {$_.name -eq "Collation"}|select value 
    $IsClustered =$s | where {$_.name -eq "IsClustered"}|select value 
    $ProductLevel =$s | where {$_.name -eq "ProductLevel"}|select value 
    $ComputerNamePhysicalNetBIOS =$s | where {$_.name -eq "ComputerNamePhysicalNetBIOS"}|select value 
    $ResourceLastUpdateDateTime =$s | where {$_.name -eq "ResourceLastUpdateDateTime"}|select value 
    $AuditLevel =$st | where {$_.name -eq "AuditLevel"}|select value 
    $BackupDirectory =$st | where {$_.name -eq "BackupDirectory"}|select value 
    $DefaultFile =$st | where {$_.name -eq "DefaultFile"}|select value 
    $DefaultLog =$st | where {$_.name -eq "DefaultLog"}|select value 
    $LoginMode =$st | where {$_.name -eq "LoginMode"}|select value 
    $min=$CP | where {$_.Displayname -like "*min server memory*"}|select configValue 
    $max=$CP | where {$_.Displayname -like "*max server memory*"}|select configValue 
    $xp_cmdshell=$CP | where {$_.Displayname -like "*xp_cmdshell*"}|select configValue 
    $FQDN=[System.DirectoryServices.ActiveDirectory.Domain]::GetCurrentDomain().Name 
    $IPAddress=(Get-WmiObject Win32_NetworkAdapterConfiguration -ComputerName $instanceName | ? {$_.IPEnabled}).ipaddress 
    $a=''
    $server1.EnumActiveGlobalTraceFlags()| % {
     [string]$b=$_.status
     [string]$c=$_.TraceFlag
     $a+=$c.ToString() +'->'+ $b.ToString() + ' '
     
     }
     
    If ($rmo.DistributorInstalled -or $rmo.IsDistributor -or $rmo.IsPublisher -or $smo.RegisteredSubscribers) {
    $replication= "1"
    }
    else
    {
    $replication= "0"
    }
    $SQL= $server1 | select ServiceAccount,ServiceStartMode,State
    
    
    
    Foreach($Database in $server1.Databases)
     {
     if($Database.IsMirroringEnabled){$ismirror="1"} else { $ismirror="0"}
     }
     
    if ($HasNullSaPassword.value -eq $NULL) 
    { 
     $HasNullSaPassword.value='No' 
    } 
    if($DefaultFile.value -eq '') 
    { 
     $DefaultFile.value='NA' 
    } 
    if ($VersionString.value -like '8*') 
    { 
     $SQLServer='SQL SERVER 2000' 
    } 
    elseif ($VersionString.value -like '9*') 
    { 
     $SQLServer='SQL SERVER 2005' 
    } 
    elseif ($VersionString.value -like '10.0*') 
    { 
     $SQLServer='SQL SERVER 2008' 
    } 
    elseif ($VersionString.value -like '10.5*') 
    { 
     $SQLServer='SQL SERVER 2008 R2' 
    } 
    elseif ($VersionString.value -like '11*') 
    { 
     $SQLServer='SQL SERVER 2012' 
    } 
    else 
    { 
     $SQLServer='Invalid' 
    } 
     
     
    if ($OSVersion.value -like '5.0*') 
    { 
     $OSVer='Windows 2000' 
    } 
    elseif ($OSVersion.value -like '5.1*') 
    { 
     $OSVer='Windows XP' 
    } 
    elseif ($OSVersion.value -like '5.2*') 
    { 
     $OSVer='Windows Server 2003' 
    } 
    elseif ($OSVersion.value -like '6.0*') 
    { 
     $OSVer='Windows Server 2008' 
    } 
    elseif ($OSVersion.value -like '6.1*') 
    { 
     $OSVer='Windows Server 2008 R2' 
    } 
    elseif ($OSVersion.value -like '6.2*') 
    { 
     $OSVer='Windows Server 2012' 
    } 
    else 
    { 
     $OSVer='NA' 
    } 
     $Sheet.Cells.Item($intRow,1) =$instanceName 
     $Sheet.Cells.Item($intRow,2) =$ComputerNamePhysicalNetBIOS.value 
     $Sheet.Cells.Item($intRow,3) =$NetName.value 
     $Sheet.Cells.Item($intRow,4) =$OSVer 
     $Sheet.Cells.Item($intRow,5) =$OSVersion.value 
     $Sheet.Cells.Item($intRow,6) = $Platform.value 
     $Sheet.Cells.Item($intRow,7) = $Product.value 
     $Sheet.Cells.Item($intRow,8) = $edition.value 
     $Sheet.Cells.Item($intRow,9) = $SQLServer 
     $Sheet.Cells.Item($intRow,10) = $VersionString.value 
     $Sheet.Cells.Item($intRow,11) = $ProductLevel.value 
     $Sheet.Cells.Item($intRow,12) = $Dbs 
     $Sheet.Cells.Item($intRow,13) = $HasNullSaPassword.value 
     $Sheet.Cells.Item($intRow,14) = $IsCaseSensitive.value 
     $Sheet.Cells.Item($intRow,15) = $IsFullTextInstalled.value 
     $Sheet.Cells.Item($intRow,16) = $Language.value 
     $Sheet.Cells.Item($intRow,17) = $LoginMode.value 
     $Sheet.Cells.Item($intRow,18) = $Processors.value 
     $Sheet.Cells.Item($intRow,19) = $PhysicalMemory.value 
     $Sheet.Cells.Item($intRow,10) = $Max.Configvalue 
     $Sheet.Cells.Item($intRow,21) = $Min.Configvalue 
     $Sheet.Cells.Item($intRow,22) = $IsSingleUser.value 
     $Sheet.Cells.Item($intRow,23) = $IsClustered.value 
     $Sheet.Cells.Item($intRow,24) = $Collation.value 
     $Sheet.Cells.Item($intRow,25) = $MasterDBLogPath.value 
     $Sheet.Cells.Item($intRow,26) = $MasterDBPath.value 
     $Sheet.Cells.Item($intRow,27) = $ErrorLogPath.value 
     $Sheet.Cells.Item($intRow,28) = $BackupDirectory.value 
     $Sheet.Cells.Item($intRow,29) = $DefaultLog.value 
     $Sheet.Cells.Item($intRow,20) = $ResourceLastUpdateDateTime.value 
     $Sheet.Cells.Item($intRow,31) = $AuditLevel.value 
     $Sheet.Cells.Item($intRow,32) = $DefaultFile.value 
     $Sheet.Cells.Item($intRow,33) = $xp_cmdshell.Configvalue 
     $Sheet.Cells.Item($intRow,34) = $FQDN 
     $Sheet.Cells.Item($intRow,35) = ($IPAddress -join ',') 
     $Sheet.Cells.Item($intRow,36) = ($a -join ',')
     $Sheet.Cells.Item($intRow,37) = $replication 
     $Sheet.Cells.Item($intRow,38) = $isMirror
     $Sheet.Cells.Item($intRow,39) = $SQL.ServiceAccount 
     $Sheet.Cells.Item($intRow,40) = $SQL.ServiceStartMode
     $Sheet.Cells.Item($intRow,41) = $SQL.State
     
    $intRow ++ 
     
    } 
     
    $filename = "$DirectoryToSaveTo$filename.xlsx" 
    if (test-path $filename ) { rm $filename } #delete the file if it already exists 
    $Sheet.UsedRange.EntireColumn.AutoFit() 
    cls 
    $Excel.SaveAs($filename, $xlOpenXMLWorkbook) #save as an XML Workbook (xslx) 
    $Excel.Saved = $True 
    $Excel.Close() 
     
     }
     ElseIf( $OutputType -eq 'csv')
     {
     $filename = "$DirectoryToSaveTo$filename.csv" 
     if (test-path $filename ) { rm $filename } #delete the file if it already exists 
     foreach ($instanceName in Get-Content $InputFileName) 
    { 
    [System.Reflection.Assembly]::LoadWithPartialName('Microsoft.SqlServer.SMO') | out-null 
    [System.Reflection.Assembly]::LoadWithPartialName("Microsoft.SqlServer.Replication") | out-null
    $server1 = New-Object -Type Microsoft.SqlServer.Management.Smo.Server -ArgumentList $instanceName 
    $rmo = New-Object Microsoft.SqlServer.Replication.ReplicationServer($instanceName) -erroraction 'silentlycontinue'
    $s=$server1.Information.Properties |Select Name, Value 
    $st=$server1.Settings.Properties |Select Name, Value 
    $CP=$server1.Configuration.Properties |Select DisplayName, Description, RunValue, ConfigValue 
    $dbs=$server1.Databases.count 
    $BuildNumber=$s | where {$_.name -eq "BuildNumber"}|select value 
    $edition=$s | where {$_.name -eq "edition"}|select value 
    $ErrorLogPath =$s | where {$_.name -eq "ErrorLogPath"}|select value 
    $HasNullSaPassword =$s | where {$_.name -eq "HasNullSaPassword"}|select value 
    $IsCaseSensitive =$s | where {$_.name -eq "IsCaseSensitive"}|select value 
    $Platform =$s | where {$_.name -eq "Platform"}|select value 
    $IsFullTextInstalled =$s | where {$_.name -eq "IsFullTextInstalled"}|select value 
    $Language =$s | where {$_.name -eq "Language"}|select value 
    $MasterDBLogPath =$s | where {$_.name -eq "MasterDBLogPath"}|select value 
    $MasterDBPath =$s | where {$_.name -eq "MasterDBPath"}|select value 
    $NetName =$s | where {$_.name -eq "NetName"}|select value 
    $OSVersion =$s | where {$_.name -eq "OSVersion"}|select value 
    $PhysicalMemory =$s | where {$_.name -eq "PhysicalMemory"}|select value 
    $Processors =$s | where {$_.name -eq "Processors"}|select value 
    $IsSingleUser =$s | where {$_.name -eq "IsSingleUser"}|select value 
    $Product =$s | where {$_.name -eq "Product"}|select value 
    $VersionString =$s | where {$_.name -eq "VersionString"}|select value 
    $Collation =$s | where {$_.name -eq "Collation"}|select value 
    $IsClustered =$s | where {$_.name -eq "IsClustered"}|select value 
    $ProductLevel =$s | where {$_.name -eq "ProductLevel"}|select value 
    $ComputerNamePhysicalNetBIOS =$s | where {$_.name -eq "ComputerNamePhysicalNetBIOS"}|select value 
    $ResourceLastUpdateDateTime =$s | where {$_.name -eq "ResourceLastUpdateDateTime"}|select value 
    $AuditLevel =$st | where {$_.name -eq "AuditLevel"}|select value 
    $BackupDirectory =$st | where {$_.name -eq "BackupDirectory"}|select value 
    $DefaultFile =$st | where {$_.name -eq "DefaultFile"}|select value 
    $DefaultLog =$st | where {$_.name -eq "DefaultLog"}|select value 
    $LoginMode =$st | where {$_.name -eq "LoginMode"}|select value 
    $min=$CP | where {$_.Displayname -like "*min server memory*"}|select configValue 
    $max=$CP | where {$_.Displayname -like "*max server memory*"}|select configValue 
    $xp_cmdshell=$CP | where {$_.Displayname -like "*xp_cmdshell*"}|select configValue 
    $FQDN=[System.DirectoryServices.ActiveDirectory.Domain]::GetCurrentDomain().Name 
    $IPAddress=(Get-WmiObject Win32_NetworkAdapterConfiguration -ComputerName $instanceName | ? {$_.IPEnabled}).ipaddress 
    $a=''
    $server1.EnumActiveGlobalTraceFlags()| % { 
     [string]$b=$_.status
     [string]$c=$_.TraceFlag
     $a+=$c.ToString() +'->'+ $b.ToString()+ ' '
     
     }
     
     
    If ($rmo.DistributorInstalled -or $rmo.IsDistributor -or $rmo.IsPublisher -or $smo.RegisteredSubscribers) {
    $replication= "1"
    }
    else
    {
    $replication= "0"
    }
    $SQL= $server1 | select ServiceAccount,ServiceStartMode,State
    
    
    Foreach($Database in $server1.Databases)
     {
     if($Database.IsMirroringEnabled){$ismirror="1"} else { $ismirror="0"}
     }
     
    if ($HasNullSaPassword.value -eq $NULL) 
    { 
     $HasNullSaPassword.value='No' 
    } 
    if($DefaultFile.value -eq '') 
    { 
     $DefaultFile.value='NA' 
    } 
    if ($VersionString.value -like '8*') 
    { 
     $SQLServer='SQL SERVER 2000' 
    } 
    elseif ($VersionString.value -like '9*') 
    { 
     $SQLServer='SQL SERVER 2005' 
    } 
    elseif ($VersionString.value -like '10.0*') 
    { 
     $SQLServer='SQL SERVER 2008' 
    } 
    elseif ($VersionString.value -like '10.5*') 
    { 
     $SQLServer='SQL SERVER 2008 R2' 
    } 
    elseif ($VersionString.value -like '11*') 
    { 
     $SQLServer='SQL SERVER 2012' 
    } 
    else 
    { 
     $SQLServer='Invalid' 
    } 
     
     
    if ($OSVersion.value -like '5.0*') 
    { 
     $OSVer='Windows 2000' 
    } 
    elseif ($OSVersion.value -like '5.1*') 
    { 
     $OSVer='Windows XP' 
    } 
    elseif ($OSVersion.value -like '5.2*') 
    { 
     $OSVer='Windows Server 2003' 
    } 
    elseif ($OSVersion.value -like '6.0*') 
    { 
     $OSVer='Windows Server 2008' 
    } 
    elseif ($OSVersion.value -like '6.1*') 
    { 
     $OSVer='Windows Server 2008 R2' 
    } 
    elseif ($OSVersion.value -like '6.2*') 
    { 
     $OSVer='Windows Server 2012' 
    } 
    else 
    { 
     $OSVer='NA' 
    } 
    
    
     $Properties = @{Name=$instanceName 
     ComputerNamePhysicalNetBIOS =$ComputerNamePhysicalNetBIOS.value 
     NetName =$NetName.value 
     OSVer =$OSVer 
     OSVersion =$OSVersion.value 
     Platform = $Platform.value 
     Product = $Product.value 
     edition = $edition.value 
     SQLServer = $SQLServer 
     VersionString = $VersionString.value 
     ProductLevel = $ProductLevel.value 
     DbCount = $Dbs 
     HasNullSaPassword = $HasNullSaPassword.value 
     IsCaseSensitive = $IsCaseSensitive.value 
     IsFullTextInstalled = $IsFullTextInstalled.value 
     Language = $Language.value 
     LoginMode = $LoginMode.value 
     Processors = $Processors.value 
     PhysicalMemory = $PhysicalMemory.value 
     MaxMem = $Max.Configvalue 
     MinMem = $Min.Configvalue 
     IsSingleUser = $IsSingleUser.value 
     IsClustered = $IsClustered.value 
     Collation = $Collation.value 
     MasterDBLogPath = $MasterDBLogPath.value 
     MasterDBPath = $MasterDBPath.value 
     ErrorLogPath = $ErrorLogPath.value 
     BackupDirectory = $BackupDirectory.value 
     DefaultLog = $DefaultLog.value 
     ResourceLastUpdateDateTime = $ResourceLastUpdateDateTime.value 
     AuditLevel = $AuditLevel.value 
     DefaultFile = $DefaultFile.value 
     xp_cmdshell = $xp_cmdshell.Configvalue 
     FQDN = $FQDN 
     IPAddress = ($IPAddress -join ',')
     Traceflag = ($a -join ',')
     Replication = $replication 
     Mirroring = $isMirror
     ServiceAccount = $SQL.ServiceAccount 
     ServiceStartMode = $SQL.ServiceStartMode
     State = $SQL.State
     }
    
    $Results += New-Object psobject -Property $properties 
    ####Comment the below line, if you wish to not to display an output to the console
    $Results
    #####
    $results | select Name ,ComputerNamePhysicalNetBIOS,NetName ,OSVer,OSVersion,Platform,Product,edition,SQLServer,VersionString,ProductLevel,DbCount,HasNullSaPassword,IsCaseSensitive,IsFullTextInstalled,Language,LoginMode,Processors,PhysicalMemory,MaxMem,MinMem,IsSingleUser,IsClustered,Collation,MasterDBLogPath,MasterDBPath,ErrorLogPath,BackupDirectory,DefaultLog,ResourceLastUpdateDateTime,AuditLevel,DefaultFile,xp_cmdshell,FQDN,IPAddress,Traceflag,Replication,Mirroring,ServiceAccount,ServiceStartMode,State| export-csv -Path $filename -NoTypeInformation
    
     }
     
     }
     
     
     
     
    Function sendEmail([string]$emailFrom, [string]$emailTo, [string]$subject,[string]$body,[string]$smtpServer,[string]$filePath) 
    { 
    #initate message 
    $email = New-Object System.Net.Mail.MailMessage 
    $email.From = $emailFrom 
    $email.To.Add($emailTo) 
    $email.Subject = $subject 
    $email.Body = $body 
    # initiate email attachment 
    $emailAttach = New-Object System.Net.Mail.Attachment $filePath 
    $email.Attachments.Add($emailAttach) 
    #initiate sending email 
    $smtp = new-object Net.Mail.SmtpClient($smtpServer) 
    $smtp.Send($email) 
    } 
    
    
    If( $Email -eq 'Yes')
    {
    If (!($to) -and !($smtp))
    { 
    #Call Function 
    sendEmail -emailFrom $from -emailTo $to "SQL INVENTORY" "SQL INVENTORY DETAILS - COMPLETE DETAILS" -smtpServer $SMTP -filePath $filename 
    }
    else
    {
    write-host 'To or SMTP Invalid'
    }
    }
    
    
    
    
    

     

    Output

    CSV:

    Inventory

     

    CSV output to saved under f:\PowerSQL folder

    Inventory_1

     

    Excel

    Inventory_3



    SQL SERVER – Install Error – Could not Find the Database Engine Startup Handle

    $
    0
    0

    Note: There are multiple reason of above error and this blog shows just one of them. I am sure that this blog would give you guideline about what do to in case you see this error about install error.

    Some errors are generic and there is no single path / root cause for the same. It is important to know at least the basic path one needs to take while troubleshooting. One of the reasons of loving my consultancy job is that I learn something new every day. I found myself again in learning state when I was trying to help one of my clients to assist in installation of SQL Server in a new environment. While installing SQL, it was stuck at below error message.

    Whenever I see any error in the setup, I start looking at setup logs. One thing which I have learned in the past is that whenever we see “Could not find the Database Engine startup handle” it is mostly due to SQL service startup failure during installation. We had no other option than hitting OK. At the end, I looked into the Summary.txt file as pointed at the last screen. Here is what I found:

    Feature: Database Engine Services
    Status: Failed: see logs for details
    Reason for failure: An error occurred during the setup process of the feature.
    Next Step: Use the following information to resolve the error, uninstall this feature, and then run the setup process again.
    Component name: SQL Server Database Engine Services Instance Features
    Component error code: 0x851A0019
    Error description: Could not find the Database Engine startup handle.

    In the setup logs folder, we should have a file with name “SQLServer_ERRORLOG_<DATETIME>” which is saved copy of ERRORLOG when SQL was unable to start. Here is what we found in that file.

    Cannot use file ‘M:\MSSQL11.MSSQLSERVER\MSSQL\DATA\master.mdf’ because it was originally formatted with sector size 4096 and is now on a volume with sector size 2097152. Move the file to a volume with a sector size that is the same as or smaller than the original sector size.
    Cannot use file ‘L:\MSSQL11.MSSQLSERVER\MSSQL\DATA\mastlog.ldf’ because it was originally formatted with sector size 4096 and is now on a volume with sector size 2097152. Move the file to a volume with a sector size that is the same as or smaller than the original sector size.

    Since this is about sector size, I referred KB

    https://support.microsoft.com/en-us/kb/926930 (Hard disk drive sector-size support boundaries in SQL Server)

    This doesn’t list that big number 2097152. Since it was an issue due to hardware, I asked them to contact Vendor and they provided a fix.

    Reference: Pinal Dave (http://blog.sqlauthority.com)

    First appeared on SQL SERVER – Install Error – Could not Find the Database Engine Startup Handle

    SQL SERVER Installation – FeatureUpgradeMatrixCheck (SQL Server 2016 Feature Upgrade) setup rule failed

    $
    0
    0

    One of the best ways to learn problems faced by individuals and organizations is to look at the forums for these issues. Often I have visited MSDN forums and see if there are some hot or interesting issues. Sometimes it is interesting to see some setup failures and investigate for the root cause. They might look trivial, but the best part is going the path of troubleshooting can be refreshing and gives you immense satisfaction to how things work inside SQL Server or Windows. This blog is inspired by one such error that encountered and I found it interesting enough to share it on this blog for the benefit of a larger audience. Let us learn about SQL Server Installation Error.

    Recently there was a post where failure of rule FeatureUpgradeMatrixCheck was reported.

    Rule “SQL Server 2016 Feature Upgrade” failed.

    The specified edition upgrade from source Enterprise edition to target Evaluation edition is not supported. For information about supported upgrade paths, see the SQL Server 2016 version and edition upgrade in Books Online.

    I looked into Detail.txt and I have highlighted the line which explains the crux of the problem.

    (17) 2016-07-11 03:05:42 Slp: Initializing rule : SQL Server 2016 Feature Upgrade
    (17) 2016-07-11 03:05:42 Slp: Rule is will be executed : True
    (17) 2016-07-11 03:05:42 Slp: Init rule target object: Microsoft.SqlServer.Configuration.SetupExtension.SkuUpgradeRule
    (17) 2016-07-11 03:05:42 Slp: — SkuUpgradeRule : Rule ‘FeatureUpgradeMatrixCheck’ looking for previous version upgrade data for feature package ‘sql_as_Cpu64’.
    (17) 2016-07-11 03:05:42 Slp: — SkuUpgradeRule : Rule ‘FeatureUpgradeMatrixCheck’ feature package ‘sql_as_Cpu64’ found no upgrade features.
    (17) 2016-07-11 03:05:42 Slp: — SkuUpgradeRule : Rule ‘FeatureUpgradeMatrixCheck’ looking for previous version upgrade data for feature package ‘sql_engine_core_inst_Cpu64’.
    (17) 2016-07-11 03:05:42 Slp: — SkuUpgradeRule : Found feature package ‘sql_engine_core_inst_SQL14_Cpu64’ with SkuValue=ENTERPRISE (Enterprise) ProductVersion=12.0.2000.8
    (17) 2016-07-11 03:05:42 Slp: — SkuUpgradeRule : Rule ‘FeatureUpgradeMatrixCheck’ found sourceVersion 12.0.0 and edition ENTERPRISE for feature package ‘sql_engine_core_inst_Cpu64’.
    (17) 2016-07-11 03:05:42 Slp: — SkuPublicConfigObject : ValidateSkuMatrix checking sku matrix for sourceVersion=12.0.0 sourceEdition=ENTERPRISE (Enterprise) sourceArchitecture=X64 targetEdition=EVAL (Evaluation) targetArchitecture=X64
    (17) 2016-07-11 03:05:42 Slp: — SkuPublicConfigObject : ValidateSkuMatrix source and target architecture match.
    (17) 2016-07-11 03:05:42 Slp: — SkuPublicConfigObject : ValidateSkuMatrix did not find a match in sku matrix .
    (17) 2016-07-11 03:05:42 Slp: — SkuUpgradeRule : Rule ‘FeatureUpgradeMatrixCheck’ feature package ‘sql_engine_core_inst_Cpu64’ is blocking upgrade.
    (17) 2016-07-11 03:05:42 Slp: — SkuUpgradeRule : Rule ‘FeatureUpgradeMatrixCheck’ detection result: IsValidFeatureUpgrade=False
    (17) 2016-07-11 03:05:42 Slp: Evaluating rule : FeatureUpgradeMatrixCheck
    (17) 2016-07-11 03:05:42 Slp: Rule running on machine: LAB-SQL-SERVER
    (17) 2016-07-11 03:05:42 Slp: Rule evaluation done : Failed
    (17) 2016-07-11 03:05:42 Slp: Rule evaluation message: The specified edition upgrade from source Enterprise edition to target Evaluation edition is not supported. For information about supported upgrade paths, see the SQL Server 2016 version and edition upgrade in Books Online.

    Whenever there are issues with upgrade, I always look for topic “Supported Version and Edition Upgrades”

    If we look at source edition, its ENTERPRISE and target is EVAL. Here is the document for SQL Server 2016.

    As per books online “SQL Server 2014 Enterprise” can only be upgraded to “SQL Server 2016 Enterprise” and “SQL Server 2016 Business Intelligence” and hence the error.

    Have you ever faced similar rule failure? How did you fix them?

    Reference: Pinal Dave (http://blog.sqlauthority.com)

    First appeared on SQL SERVER Installation – FeatureUpgradeMatrixCheck (SQL Server 2016 Feature Upgrade) setup rule failed

    PowerSQL – Get SQL TraceFlag SQL Service and Config Information

    $
    0
    0

    Get SQL Server configuration, service info, start type along with enabled Trace Flags of local or remote servers.

    This script outputs sql server configuration, service, start type, Service Account along with startup trace flags. The script will work on SQL Server 2005 and up.

    function Get-SQLAndGlobalTraceFlagsDetails { 
    <# 
    .SYNOPSIS 
    Returns SQL Server Configuration, Service and global TraceFlag details 
     
    .DESCRIPTION 
    Get-SQLAndGlobalTraceFlagsDetails is a function that returns server high level server configuration information for 
    one or more Microsoft SQL Server 
     
    .PARAMETER ComputerName 
    The computer that is running Microsoft SQL Server that you’re targeting 
     
    .EXAMPLE 
    Get-SQLAndGlobalTraceFlagsDetails -ComputerName sql01 
     
    .EXAMPLE 
    Get-SQLAndGlobalTraceFlagsDetails -ComputerName HQDBSP18 
     
    .EXAMPLE 
    "hqdbst03","hqdbsp16" | % { Get-SQLAndGlobalTraceFlagsDetails -ServerName $_ } 
     
    .EXAMPLE 
     
    ForEach ($server in Get-ChildItem C:\server.txt) 
    { 
    Get-SQLAndGlobalTraceFlagsDetails -ServerName $server 
     
    } 
     
    .INPUTS 
    String 
     
    .OUTPUTS 
    PSCustomObject , console or CSV 
    #> 
    [CmdletBinding()] 
    param ( 
    [Parameter(Mandatory=$true, 
    ValueFromPipelineByPropertyName=$true)] 
    [Alias('ServerName','PSComputerName','ComputerName')] 
    [string[]]$Ser 
    ) 
     
     
    # Used to store the result 
     
    $Results = @() 
     
    # The below array used to concatenate the Trace flag details 
     
    $TraceFlag=@() 
     
    #create an smo object for the SQL Server 
    [System.Reflection.Assembly]::LoadWithPartialName("Microsoft.SqlServer.Smo")|out-null 
     
    $SQLServer = new-object ('Microsoft.SQLServer.Management.Smo.Server') $Ser 
    $SQL= $SQLServer | select Name, Edition, BuildNumber, Product, ProductLevel, Version, Processors, PhysicalMemory, DefaultFile, DefaultLog, MasterDBPath, MasterDBLogPath, BackupDirectory, ServiceAccount,ServiceStartMode,State 
     
    $SQLServer.EnumActiveGlobalTraceFlags()|%{ 
    [string]$b=$_.status 
    [string]$c=$_.TraceFlag 
    $TraceFlag+=$c.ToString() +'->'+ $b.ToString() 
     
    } 
     
    $Properties = @{ 
    Name = $SQL.name 
    Edition = $SQL.Edition 
    BuildNumber = $SQL.BuildNumber 
    Product=$SQL.Product 
    ProductLevel=$SQL.ProductLevel 
    Version=$SQL.Version 
    Processors=$SQL.Processors 
    DefaultLog=$SQL.DefaultLog 
    MasterDBPath=$SQL.MasterDBPath 
    MasterDBLogPath=$SQL.MasterDBLogPath 
    BackupDirectory=$SQL.BackupDirectory 
    ServiceAccount=$SQL.ServiceAccount 
    StartupMode=$SQL.ServiceStartMode 
    State=$SQL.State 
    TraceAndStatus=($TraceFlag -join ',')} 
     
     
     
    $Results += New-Object psobject -Property $properties  
    $Results | Select-Object Name, Edition, BuildNumber,TraceAndStatus,Product,ProductLevel,Version,Processors,DefaultLog,MasterDBPath,MasterDBLogPath,BackupDirectory,ServiceAccount,StartupMode,State 
     
     
    } 
     
    "hqdbst03","hqdbsp16" | % { Get-SQLAndGlobalTraceFlagsDetails1 -ServerName $_ }
     SQLTraceFlag

    SQL SERVER – Unable to Create Listener for AlwaysOn Availability Group in Azure via Template Deployment

    $
    0
    0

    Recently I was trying to help a customer who was deploying AlwaysOn Availability Group in Microsoft Azure via template deployment.

    The template was failing with below error

    StatusMessage
    {
    “status”: “Failed”,
    “error”: {
    “code”: “ResourceDeploymentFailure”,
    “message”: “The resource operation completed with terminal provisioning state ‘Failed’.”,
    “details”: [
    {
    “code”: “DeploymentFailed”,
    “message”: “At least one resource deployment operation failed. Please list deployment operations for details. Please see https://aka.ms/arm-debug for usage details.”,
    “details”: [
    {
    “code”: “Conflict”,
    “message”: “{\r\n \”status\”: \”Failed\”,\r\n \”error\”: {\r\n \”code\”: \”ResourceDeploymentFailure\”,\r\n \”message\”: \”The resource operation completed with terminal provisioning state ‘Failed’.\”,\r\n \”details\”: [\r\n {\r\n \”code\”: \”VMExtensionProvisioningError\”,\r\n \”message\”: \”VM has reported a failure when processing extension ‘configuringAlwaysOn’. Error message: \\\”DSC Configuration ‘CreateFailoverCluster’ completed with error(s). Following are the first few: PowerShell DSC resource MicrosoftAzure_xSqlAvailabilityGroupListener failed to execute Set-TargetResource functionality with error message: The running command stopped because the preference variable \\\”ErrorActionPreference\\\” or common parameter is set to Stop: An error occurred while attempting to bring the resource ‘SQLAUTHORITY-AG’ online.\\n The cluster resource could not be brought online by the resource monitor The SendConfigurationApply function did not succeed.\\\”.\”\r\n }\r\n ]\r\n }\r\n}”
    }
    ] }
    ] }

    The message looks very ugly, but it’s a direct copy paste from Azure. Here is the relevant message:

    An error occurred while attempting to bring the resource ‘SQLAUTHORITY-AG’ online. The cluster resource could not be brought online by the resource monitor

    I looked further into Event log into the node and found below interesting error.

    Log Name: System
    Source: Microsoft-Windows-FailoverClustering
    Date: 7/26/2016 6:11:45 PM
    Event ID: 1193
    Task Category: Network Name Resource
    Level: Error
    Keywords:
    User: SYSTEM
    Computer: demo.sqlauthority.local
    Description:
    Cluster network name resource ‘alwayson-ag-sqlauth-listener01’ failed to create its associated computer object in domain ‘sqlauthority.local’ for the following reason: Resource online.
    The associated error code is: -1073741790
    Please work with your domain administrator to ensure that:
    – The cluster identity ‘win-cluster$’ can create computer objects. By default all computer objects are created in the ‘Computers’ container; consult the domain administrator if this location has been changed.
    – The quota for computer objects has not been reached.
    – If there is an existing computer object, verify the Cluster Identity ‘win-cluster$’ has ‘Full Control’ permission to that computer object using the Active Directory Users and Computers tool.

    Interesting thing was that the deployment worked first time but failed second time and all subsequent attempts.

    Initially I thought it’s a well-known permission issue of CNO and VCO so I went to pre-stage it.  (Prestage Cluster Computer Objects in Active Directory Domain Services)

    Later, we found that listener name was created in AD as “alwayson-ag-sq” due to 15 characters’ limit. When we deployed again, it was still creating same name even though I gave ‘alwayson-ag-sqlauth-listener01’ in template.

    Solution: Make sure we are keeping computer names within the limit of 15 characters. (Naming conventions in Active Directory for computers, domains, sites, and OUs)

    Reference: Pinal Dave (http://blog.sqlauthority.com)

    First appeared on SQL SERVER – Unable to Create Listener for AlwaysOn Availability Group in Azure via Template Deployment

    SQL SERVER – Setting Firewall Settings With Azure SQL Server VMs

    $
    0
    0

    Recently I had a session around using SQL Server on Azure and during this session one of the questions was to access the SQL Server in a Hybrid Setup. This is a typical scenario wherein the developer was requesting to connect to the SQL Server running on a VM from his application that was sitting inside his environment. Though there were specific steps that needed to be taken, he was getting some error. Let us learn about how to setup firewall with Azure SQL Server VMs.

    After a moment of debugging, I realized it was a problem of Firewall. Though the initial test was by disabling the Firewall I was able to get the connectivity working. I enabled it immediately and then started to get into configuring the Firewall for exception for SQL Server traffic. This blog is more of a tutorial on how I was configuring the same.

    Steps to enable the SQL Server traffic

    To enable connection to the SQL Server from on-premises applications, you must open port 1433 on the SQL Server VM. Though this is an example, you need to see if you can change and use some other port for SQL Server connection. But this is reserved for some other time. The following steps will lead you through this:

    1. Login to SQL Server VM and Open firewall settings
    2. Create an inbound rule for the TCP port 1433 to allow connections

    1. Follow the default values on the wizard for the next steps and name the rule ‘SQL TCP’ and click OK.

    Alternatively, you can use execute this PowerShell cmdlet to configure inbound firewall rule:

    netsh advfirewall firewall add rule name='SQL Server (TCP-In)' program='C:\Program Files\Microsoft SQL Server\MSSQL11.MSSQLSERVER\MSSQL\Binn\sqlservr.exe' dir=in action=allow protocol=TCP 

    This is an important step one needs to configure when working with VMs on Azure to access SQL Server. Though I have started to explore some of the core capabilities that come when working with Azure, I still see there are nuances that are quite different when compared to how an on-premise SQL Server would be. I am sure DBA’s and administrators are struggling to understand these use-cases that need to be configured because they have been used to connecting to SQL Server directly when working on their data centers.

    Having said that, I felt this was something common and people are aware. But since I have done in my consulting couple of times in the past month that I get to write them down too.

    Reference: Pinal Dave (http://blog.sqlauthority.com)

    First appeared on SQL SERVER – Setting Firewall Settings With Azure SQL Server VMs

    SQL Complete – Smart Code Completion and SQL Formatting

    $
    0
    0

    A week ago, I saw a notification about the release of dbForge SQL Complete 5.5. As a long-time user of this product, I have updated to the new version. A week later I decided to share my impressions of the new version of SQL Complete.

    The first thing that immediately caught my attention is the integration with SSMS 2016, which has recently become my main working tool. The new version of SSMS now includes a huge number of innovations, including Live Query Statistics that won my heart…

    In addition to the SSMS 2016 integration, the new syntax of SQL Server 2016 was supported in SQL Complete. Previously, when writing articles on the new syntax, I had to look in MSDN sometimes, and now there is no necessity:

    Previously, when typing GROUP or ORDER, BY was added automatically, and it seemed like a small revolution. In the new version, I liked the further development of this idea – to prompt more syntactic structures:

    It is worth noting that phrase suggestion was implemented for DDL constructions:

    Note also an improved suggestion inside the CROSS/OUTER APPLY constructions. I do not know for others, but these constructions are very useful for me. With their help, you can do UNPIVOT as shown in this picture:

    As well as in individual cases influence the execution plan, forcing the optimizer to choose Index Seek when accessing data.

    The context menu now includes the new command “Execute to cursor”, which came in handy a couple of times in practice:

    What else can I say? Two new formatting profiles were added:

    Now you can save time significantly without having to set up the formatting style for each construction from scratch. Here is an example of a badly formatted query:

    select c.customername, o.orderdate,
    ol.quantity
    from sales.customers c join sales.orders o
    on c.customerid = o.customerid join sales.orderlines
    ol on o.orderid = ol.orderid
    where c.isoncredithold = 0 and ol.unitprice &amp;gt; 0 order by o.orderdate desc,
    ol.quantity

    If you choose the first profile, after formatting you will get the following beauty:

    SELECT c.CustomerName
         , o.OrderDate
         , ol.Quantity
    FROM Sales.Customers c
        JOIN Sales.Orders o ON c.CustomerID = o.CustomerID
        JOIN Sales.OrderLines ol ON o.OrderID = ol.OrderID
    WHERE c.IsOnCreditHold = 0
        AND ol.UnitPrice > 0
    ORDER BY o.OrderDate DESC
           , ol.Quantity

    If formatted with the second one, the result will be the following:

    SELECT c.CustomerName,
           o.OrderDate,
           ol.Quantity
    FROM Sales.Customers c
    JOIN Sales.Orders o ON c.CustomerID = o.CustomerID
    JOIN Sales.OrderLines ol ON o.OrderID = ol.OrderID
    WHERE c.IsOnCreditHold = 0
        AND ol.UnitPrice > 0
    ORDER BY o.OrderDate DESC,
             ol.Quantity

    A small thing, but it makes a difference.

    The rest of the improvements I saw “under the bonnet” – the speed when working with large scripts has increased (more than 1MB). This is especially true for those who often need to edit synchronization scripts of a schema or data.

    Anyone who is interested in trying out the new version of SQL Complete can download it here.

    Reference: Pinal Dave (http://blog.sqlauthority.com)

    First appeared on SQL Complete – Smart Code Completion and SQL Formatting

    8 Ways To Be Successful With Microsoft Azure SQL Database

    $
    0
    0

    When I hear stories about folks that tried to migrate to Microsoft Azure SQL Database with a brute-force-single-click and failed, I ask several follow up questions. I have found a common pattern in the answers: lack of strategy.

    The post 8 Ways To Be Successful With Microsoft Azure SQL Database appeared first on Thomas LaRock.

    If you liked this post then consider subscribing to the IS [NOT] NULL newsletter: http://thomaslarock.com/is-not-null-newsletter/


    SQL SERVER – Event 17058 – initerrlog: Could not Open Error Log File

    $
    0
    0

    If you have ever interacted with me or taken my services, you would notice that I always ask for ERRORLOG in almost all of my contact with my client. Once of my friend contacted me and when I asked for ERRORLOG, he informed that there is no ERRORLOG file and SQL is not getting started.  I suggested him that we should analyze event log for further details, after interestingly, we found the following details in the event 17058 about initerrlog: Could not Open Error Log File.

    Log Name: Application
    Source: MSSQLSERVER
    Event ID: 17058
    Task Category: Server
    Level: Error
    Description:
    initerrlog: Could not open error log file ”. Operating system error = 3(The system cannot find the path specified.).

    We finally found that the error occurs due to the insufficient privilege of SQL Server Service Account in the Log directory: E:\Program Files\Microsoft SQL Server\MSSQL12.MSSQLSERVER\MSSQL\Log

    Here is the fix of the issue.

    1. Start SQL Server Configuration manager.
    2. Click to select ‘SQL Server Services’ from the left menu options.
    3. On the right panel, right click on ‘SQL Server (MSSQLSERVER)’ and click ‘Properties’. You may want to choose correct service.
    4. Click ‘Startup Parameters’ tab.
    1. Note the location after -e parameter.
    2. Browse the Log location ” E:\Program Files\Microsoft SQL Server\MSSQL12.MSSQLSERVER \MSSQL\Log”.
    3. Right click on the folder “Log” and click Properties and then to visit to “Security” tab. Now, check SQL Server service account permission on this folder and give proper access to this folder.
    4. Now, Restart the SQL Server service. If you face the same error again, try to change highly privileged service account like “Local System”.

    After giving permission, we were able to start the SQL Service. Have you faced a similar error?

    Reference: Pinal Dave (http://blog.sqlauthority.com)

    First appeared on SQL SERVER – Event 17058 – initerrlog: Could not Open Error Log File

    SQL SERVER – Error: 14258 – Cannot perform this operation while SQLServerAgent is starting. Try again later

    $
    0
    0

    One of my clients asked assistance in fixing an interesting issue. They informed me that they are not able to run any job in SQL Agent. When they try to run the job manually, they are seeing below message related to SQLServerAgent .

    An exception occurred while executing a Transact-SQL statement or batch. (Microsoft.SqlServer.ConnectionInfo)
    Cannot perform this operation while SQLServerAgent is starting. Try again later. (Microsoft SQL Server, Error: 14258)

    My initial search showed me below KB BUG: DTC Transactions May Fail When SQL Server Is Running in Lightweight Pooling Mode.

    But above is not applicable as we were running SQL Server 2012 and fiber mode was not enabled. I went ahead and asked SQLAgent.out file to see if there is something interesting

    2016-07-21 16:22:49 – ? [297] SQLServer Message: 15457, Configuration option ‘Agent XPs’ changed from 0 to 1. Run the RECONFIGURE statement to install. [SQLSTATE 01000] (DisableAgentXPs)
    2016-07-21 16:22:50 – ? [100] Microsoft SQLServerAgent version 10.50.4000.0 (x86 unicode retail build) : Process ID 3748
    2016-07-21 16:22:50 – ? [101] SQL Server IND-SAP-SQL version 10.50.4000 (0 connection limit)
    2016-07-21 16:22:50 – ? [102] SQL Server ODBC driver version 10.50.4000
    2016-07-21 16:22:50 – ? [103] NetLib being used by driver is DBNETLIB.DLL; Local host server is IND-SAP-SQL
    2016-07-21 16:22:50 – ? [310] 2 processor(s) and 2048 MB RAM detected
    2016-07-21 16:22:50 – ? [339] Local computer is IND-SAP-SQL running Windows NT 5.2 (3790) Service Pack 2
    2016-07-21 16:22:52 – ! [364] The Messenger service has not been started – NetSend notifications will not be sent
    2016-07-21 16:22:52 – ? [129] SQLSERVERAGENT starting under Windows NT service control
    2016-07-21 16:22:52 – ? [392] Using MAPI32.DLL from C:\WINNT\SYSTEM32 (version 1.0.2536.0)
    2016-07-21 16:22:52 – ? [196] Attempting to start mail session using profile ‘SQLSrvrSvc’…

    When I checked on my machine, my last line was not same. So, it looks like MAPI32.dll is being used. I checked further and found that they were using SQLMail which uses MAPI client to send email. We changed the setting to use Database Mail as shown below.

    Once we changed the mail profile to Database Mail, we were able to run the jobs manually.

    Reference: Pinal Dave (http://blog.sqlauthority.com)

    First appeared on SQL SERVER – Error: 14258 – Cannot perform this operation while SQLServerAgent is starting. Try again later

    SQL SERVER – Installation Fails With Error – A Constraint Violation Occurred

    $
    0
    0

    In my recent past, I have helped around 10 customers who have had similar problems while installing SQL Server Cluster on windows. So I thought it would be a nice idea to pen it down as a blog post so that it can help others in future. In this blog post we will discuss about Installation Fails With Error – A Constraint Violation Occurred.

    The issue which we saw was that SQL Server cluster setup would create a network name resource in failover cluster manager and it would fail. Here is the message which we would see in the setup

    The cluster resource ‘SQL Server (SQLSQL)’ could not be brought online due to an error bringing the dependency resource ‘SQL Network Name (SAPSQL)’ online. Refer to the Cluster Events in the Failover Cluster Manager for more information.
    Click ‘Retry’ to retry the failed action, or click ‘Cancel’ to cancel this action and continue setup.

    When we look at event log, we saw below message (event ID 1194)

    Log Name: System
    Source: Microsoft-Windows-FailoverClustering
    Date: 20/06/2016 19:55:45
    Event ID: 1194
    Task Category: Network Name Resource
    Level: Error
    Keywords:
    User: SYSTEM
    Computer: NODENAME1.internal.sqlauthority.com
    Description:
    Cluster network name resource ‘SQL Network Name (SAPSQL)’ failed to create its associated computer object in domain ‘internal.sqlauthority.com’ during: Resource online.
    The text for the associated error code is: A constraint violation occurred.
    Please work with your domain administrator to ensure that:
    – The cluster identity ‘WINCLUSTER$’ has Create Computer Objects permissions. By default all computer objects are created in the same container as the cluster identity ‘WINCLUSTER$’.
    – The quota for computer objects has not been reached.
    – If there is an existing computer object, verify the Cluster Identity ‘WINCLUSTER$’ has ‘Full Control’ permission to that computer object using the Active Directory Users and Computers tool.

    Another client got “Access is denied” messages instead of “A constraint violation occurred” in above event ID. My clients have informed that they have logged in as domain admin so Access denied is impossible. Error from another client is below.

    I explained all of them that when network name is created in a cluster, it would contact active directory (AD) domain controller (DC) via Windows Cluster Network name computer account also called as CNO (Cluster Network Object). So, whatever error, we are seeing are possible because the domain admin account (windows logged in user account) is not used to create a computer object for SQL in AD.

    To solve this problem, we logged into the domain controller machine and created the Computer Account: SAPSQL (called as VCO – Virtual Computer Object). Gave the cluster name WINCLUSTER$ full control on the computer name. If we carefully read error message, we have the solution already listed there. Then clicked on the retry option in the setup. The setup continued and completed successfully.

    Solution/Workaround:

    Here are the detailed steps (generally done on a domain controller by domain admin):

    1. Start > Run > dsa.msc. This will bring up the Active Directory Users and Computers UI.
    2. Under the View menu, choose Advanced Features.
    3. If the SQL Virtual Server name is already created, then search for it else go to the appropriate OU and create the new computer object [VCO] under it.
    4. Right click on the new object created and click Properties.
    5. On the Security tab, click Add. Click Object Types and make sure that Computers is selected, then click Ok.
    6. Type the name of the CNO and click Ok. Select the CNO and under Permissions click Allow for Full Control permissions.
    7. Disable the VCO by right clicking.

    This is also known as pre-staging of the VCO.

    Hope this would help someone to save time and resolve issue without waiting for someone else assistance. Do let me know if you ever encountered the same.

    Reference: Pinal Dave (http://blog.sqlauthority.com)

    First appeared on SQL SERVER – Installation Fails With Error – A Constraint Violation Occurred

    SQL SERVER – A Timeout (30000 milliseconds) was Reached While Waiting for a Transaction Response from the MSSQLSERVER

    $
    0
    0

     Recently I was contacted by a client who reported very strange error in the SQL Server machine. These consulting engagements sometimes get the best out of you when it comes to troubleshooting. They reported that they see timeout error. My question was whether it connection timeout or query timeout which I explained in this blog post?

    They said that they are seeing below error in the System Event log and during that time they were not able to connect to SQL Server.

    Event ID: 7011
    Message: A timeout (30000 milliseconds) was reached while waiting for a transaction response from the MSSQLSERVER service.

    Once it happens, they were not able to stop SQL Server service. I asked about how do they reproduce the error or hang situation and strangely they said that it happens when they expand an Oracle Linked server in SQL Server Management Studio!!!

    I told them to reproduce the error. As soon as they expand “catalog” under linked server to oracle, it was stuck in “expanding”. Luckily, I was with them and as soon as “hang” was reproduced, I connected via DAC connection. I was able to see PREEMPTIVE_OS_GETPROCADDRESS wait for the SSMS query. As per my internet search, it is called when loading DLL. In this case, the wait for increasing continuously. So I asked them to kill the SQL process from task manager.

    As a next step, I wanted to know which is the DLL causing issue, so I captured Process Monitor while reproducing the issue. Finally, we were able to nail down that SQLServr.exe is trying to find “OraClient11.Dll” but not able to locate it.

    It didn’t take much time to conclude that the hang was caused due to incorrect value in PATH variable for Oracle DLLs used by linked server. This is also explained here.

    Solution

    We found that PATH variable was not having C:\oracle11\product\11.2.0\client_1\BIN which was the folder contains OraClient11.Dll. As soon as we added above location to PATH variable, issue was resolved.

    Reference: Pinal Dave (http://blog.sqlauthority.com)

    First appeared on SQL SERVER – A Timeout (30000 milliseconds) was Reached While Waiting for a Transaction Response from the MSSQLSERVER

    Everything Old Is New Again: 5 IT Headaches That Never Go Away

    Viewing all 552 articles
    Browse latest View live


    <script src="https://jsc.adskeeper.com/r/s/rssing.com.1596347.js" async> </script>