Retornando Informações da Conta de Serviço do SQL Server Usando Powershell


Pessoal, esses tempos nosso amigo Marcos Freccia (blog | twitter) me pediu uma maneira de veriricar qual a conta de serviço do SQL Agent. Isso é simples de fazer caso você tenha um servidor.

E se por acaso você tiver 10, 20. 100. A coisa complica ? Nem tanto…

 

supermouse

Super PowerShell seu amigooooo vai salvá-lo do Perigooooo

Passei esse script simples pro Marcos :

   1: Get-WmiObject -Class Win32_Service -Filter "Name='SQLSERVERAGENT'" | select StartName

e realmente funciona, tanto local como remoto (adiciona parametro –computername)

mas poderiamos melhorar isso, filtrar quais servidores eu quero, quais instâncias (ou todas) e exibir também se a conta faz parte de Local Admin.

Confesso que comecei meu script pensando na seguinte lógica :

  • acesso o(s)  servidores
  • acesso a(s)  instâncias
  • Para Cada uma eu acesso os dados da conta e exibo (foreach)

Foi quando me lembrei de um artigo de Don Jones (blog | twitter) , um dos maiores nomes em PowerShell (inclusive eu estou linkado na lista dele de PowrShellers heheheh Olha eu Aqui)  que dizia :

ForEach Makes me Die a Little Inside

ou o Foreach me mata um pouco por dentro.

E é verdade, na minha logica acima eu estou pensando como C#,VB ou qualquer outra linguagem de programação. Não como PowerShell. Se for para fazer assim, pra que usar PowerShell ?

Inclusive isso foi um assunto que debati com Chad Miller pois muitos profissionais estão blogando hoje sobre PowerShell, mas  não codificando em PowerShell.

Esquecem que TUDO no PowerShell é Objeto e que temos o Maravilhoso Pipeline para nos ajudar. (como ele funciona e como usar eu conto no meu Treinamento de Powershell ..vai ser legal)

Então alterei minha logica para usar o Pipeline Foreach no More.

Querem ver o script ?

   1:  

   2: function get-ServiceIsAdmin 

   3: {

   4:     [CmdletBinding()]

   5:  

   6:     Param (

   7:         [Parameter(position=0,Mandatory = $true,ValueFromPipeline = $true )][String] $ComputerName,

   8:         [Parameter(position=1,Mandatory = $true)][String] $ServiceAccount

   9:     )

  10:     process {

  11:     

  12:                 $ServiceAccountSplit = $ServiceAccount -split '\\'

  13:                 if ($ServiceAccountSplit.count -eq 1)

  14:                     { $ServiceAccountToUse = $ServiceAccountSplit[0] }

  15:                 else

  16:                     { $ServiceAccountToUse = $ServiceAccountSplit[1] }

  17:                 

  18:                 #Original Script in 

  19:                 #http://www.hanselman.com/blog/HowToDetermineIfAUserIsALocalAdministratorWithPowerShell.aspx

  20:                 

  21:                 $administratorsAccount = Get-WmiObject -ComputerName "$ComputerName" Win32_Group -filter "LocalAccount=True AND SID='S-1-5-32-544'" 

  22:                 $administratorQuery = "GroupComponent = `"Win32_Group.Domain='" + $administratorsAccount.Domain + "',NAME='" + $administratorsAccount.Name + "'`""

  23:                 $user = Get-WmiObject Win32_GroupUser -filter $administratorQuery | select PartComponent | where {$_ -match $ServiceAccountToUse}

  24:                 if ($user -eq $null ){  'No' }    else    {  'Yes' }

  25:                 

  26:     

  27:     }

  28:         

  29:  

  30: }

  31: function Get-SQLServerServiceInfo  {

  32:  

  33:  

  34:     [CmdletBinding()]

  35:  

  36:     Param (

  37:         [Parameter(position=0,Mandatory = $true,ValueFromPipeline = $true )][String] $ComputerName,

  38:         [Parameter(position=1,Mandatory = $true )][String] $SQLServerInstance = 'All',

  39:         [ValidateSet("Engine", "Agent")]

  40:         [Parameter(position=2,Mandatory = $true )][String] $ServiceType 

  41:  

  42:  

  43:     )

  44:     

  45:     begin {

  46:         

  47:         [System.Reflection.Assembly]::LoadWithPartialName('Microsoft.SqlServer.SMO') | out-null 

  48:         [System.Reflection.Assembly]::LoadWithPartialName("Microsoft.SqlServer.SqlWmiManagement") | out-null

  49:         

  50:         Function Get-ServiceByInstance ($ServiceByInstance,$InstanceName,$ReturnName) 

  51:         {

  52:             if ( -not $ReturnName) {

  53:                 [string] $ServiceAccount = ($ServiceByInstance    | where {$_.Displayname -like "*$($InstanceName)*"}    | select ServiceAccount)

  54:                 Write-Output    ($ServiceAccount.substring(17,$ServiceAccount.length  - 18))

  55:             } else {

  56:                 [string] $ServiceAccount = ($ServiceByInstance    | where {$_.Displayname -like  "*$($InstanceName)*"}    | select  Name)

  57:                 Write-Output ($ServiceAccount.substring(7,$ServiceAccount.length  - 8))

  58:         

  59:             }

  60:                 

  61:         }    

  62:     }

  63:     Process {

  64:             try {

  65:                 $ManagedComputer = New-Object ('Microsoft.SqlServer.Management.Smo.Wmi.ManagedComputer') "$ComputerName"

  66:                 $ServiceTypeShow = if ($ServiceType -eq 'Agent') {'sqlagent'} else {'SqlServer'}

  67:  

  68:                 if ($SQLServerInstance -eq 'All') { 

  69:                     $ServiceByInstance =($ManagedComputer.Services | where { $_.type -eq "$($ServiceTypeShow)"} | select DisplayName,ServiceAccount,Name)

  70:  

  71:                     $ManagedComputer.ServerInstances | select     @{Expression={$($ComputerName) };Label = "ComputerName"} ,

  72:                                                                 @{Expression={$($_.NAME) };Label = "SQLEngineInstanceName"}, 

  73:                                                                 @{Expression={Get-ServiceByInstance -ServiceByInstance $ServiceByInstance -InstanceName $($_.Name)  -ReturnName $False };Label = "ServiceAccount"},

  74:                                                                 @{Expression={get-ServiceIsAdmin -ComputerName $ComputerName -ServiceAccount (Get-ServiceByInstance -ServiceByInstance $ServiceByInstance -InstanceName $($_.Name)) };Label = "IsLocalAdmin"},

  75:                                                                 @{Expression={Get-ServiceByInstance -ServiceByInstance $ServiceByInstance -InstanceName $($_.Name)  -ReturnName $True };Label = "ServiceName"} 

  76:  

  77:  

  78:                 } else { 

  79:                 

  80:                     $ServiceByInstance =($ManagedComputer.Services | where { $_.type -eq "$($ServiceTypeShow)" -and $_.displayname -like "*$SQLServerInstance*" } | select DisplayName,ServiceAccount,Name) 

  81:                     $ManagedComputer.ServerInstances | where {$_.name -eq $SQLServerInstance }  | select     @{Expression={$($ComputerName) };Label = "ComputerName"},

  82:                                                                                                             @{Expression={$($_.NAME) };Label = "SQLEngineInstanceName"},

  83:                                                                                                             @{Expression={Get-ServiceByInstance -ServiceByInstance $ServiceByInstance -InstanceName $($_.Name) -ReturnName $false};Label = "ServiceAccount"},

  84:                                                                                                             #@{Expression={get-ServiceIsAdmin -ComputerName $ComputerName -ServiceAccount (Get-ServiceByInstance -ServiceByInstance $ServiceByInstance -InstanceName $($_.Name)) };Label = "IsLocalAdmin"},

  85:                                                                                                             @{Expression={Get-ServiceByInstance -ServiceByInstance $ServiceByInstance -InstanceName $($_.Name)  -ReturnName $True };Label = "ServiceName"}

  86:  

  87:                 }

  88:                     

  89:             } catch {

  90:                 Write-Output $Error[0]

  91:             }

  92:     

  93:     }

  94: }

  95:  

  96:  

Baixar [Updated]

as propriedades retornadas são :

  • ComputerName : Nome do Computador
  • SQLEngineInstanceName  : Nome da Instância SQL Server
  • ServiceAccount    : Conta de Serviço usada pelo SQL Server Service.
  • IsSysAdmin  : Se ServiceAccount é Adm Local da Maquina ou Não.

[Updated]

  • ServiceName – Nome do Serviço.
  • E na chamada adicionei o parametro ServiceType que pode ser Engine = Serviço do SQL Server e Agent = Serviço do SQL Agent.

E como usá-lo ?

Exemplo 1 : Quero as informações de todas as instãncias da minha maquina (local)

   1: Get-SQLServerServiceInfo  -SQLServerInstance all

 

Exemplo 2 : Quero as informações da instancia INST1 da minha maquina (local)

   1: Get-SQLServerServiceInfo  -SQLServerInstance INST1

 

Exemplo 3 : Quero as informações da maquina Server2 e todas as instãncias

   1: Get-SQLServerServiceInfo -Computername Server2 -SQLServerInstance All

 

E como escalamos este codigo ?

Se vocês perceberem, o script é uma advanced function (Treinamento de Powershell) e temos o ValueFromPipeline = $true no parametro ComputerName, ou seja, esta me dizendo que este parâmetro pode ser recebido por Pipe (Treinamento de Powershell)

Então eu posso passar uma lista de servidores  e pegar a informação de todas as instâncias SQL Server :

   1: "Server1","Server2", "Server3" | Get-SQLServerServiceInfo  -SQLServerInstance All

 

Ou Até mesmo uma lista em txt :

   1: Get-Content c:\temp\servers.txt | Get-SQLServerServiceInfo  -SQLServerInstance All

Can you see this ? Can you feel this ? Can you feel the Power ?

POWERSHELL ROCKS !!!

No matter how many times that you told me you wanted to leave
No matter how many breaths that you took, you still couldn’t breathe
No matter how many nights that you’d lie wide awake to the sound of the poison rain
Where did you go
Where did you go
Where did you go

As days go by the night’s on fire

Tell me, would you kill to save a life
Tell me, would you kill to prove you’re right?
Crash, crash, burn, let it all burn
This hurricane’s chasing us all underground

No matter how many deaths that I die, I will never forget
No matter how many lies that I live, I will never regret
There is a fire inside of this heart and a riot about to explode into flames
Where is your God
Where is your God
Where is your God

Hurricane

30 Seconds To Mars

About Laerte Junior

Laerte Junior Laerte Junior is a SQL Server specialist and an active member of WW SQL Server and the Windows PowerShell community. He also is a huge Star Wars fan (yes, he has the Darth Vader´s Helmet with the voice changer). He has a passion for DC comics and living the simple life. "May The Force be with all of us"
This entry was posted in Powershell, SQL SERVER EM GERAL, Virtual Pass BR. Bookmark the permalink.

1 Response to Retornando Informações da Conta de Serviço do SQL Server Usando Powershell

  1. Massa!
    Fiz um script aqui pra recuperar isso, mas nao ficou muito “escalavel” não..rs
    Legal sua função, parabéns mano!

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Google photo

You are commenting using your Google account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s