Управление SQL Server c помощью PowerShell

by Alexey Knyazev 5. апреля 2010 13:34

Мой доклад на TechDays.RU 

PowerShell стал неотъемлемой частью большинства новых продуктов Microsoft, в том числе и SQL Server. Данный доклад показывает всю мощь командной строки для администрирования ваших серверов БД.

Tags: , , ,

PowerShell | SQL Server

Блог переехал на платформу Windows Server 2008, IIS 7.0, ASP.Net

by Alexey Knyazev 24. марта 2010 08:42

Давно возникла такая идея и это произошло!!!

За хостинг большое спасибо .masterhost

Tags:

PowerShell | SQL Server

Экспорт таблицы пользователей в АD (PоSh)

by Alexey Knyazev 10. марта 2010 09:25

На форуме "TechNet RUS SQL Forum" появился вопрос:

Можно ли сразу из БД при помощи MS SQL перевести значения полей в AD в виде пользователей. (К примеру по фамилии имеющихся в БД людей создать пользователей в AD с логином <фамилия>)? (http://social.technet.microsoft.com/Forums/ru-RU/sqlru/thread/54ca41d0-d70c-4318-8b5c-daa7aecce9f5)

В качестве решения подобной задачи предлагаю небольшой скрипт на PowerShell.

Для начала создадим тестовую таблицу в БД с Логином и Паролей пользователей (для демонстрации всего 5 юзеров):

CREATE TABLE Users (UserLogin sysname, UserPassword nvarchar(255))
GO

INSERT INTO Users
SELECT 'SQLUser1', '1234567890'
UNION ALL
SELECT 'SQLUser2', '1234567890'
UNION ALL
SELECT 'SQLUser3', '1234567890'
UNION ALL
SELECT 'SQLUser4', '1234567890'
UNION ALL
SELECT 'SQLUser5', '1234567890

Для работы с AD буду использовать бесплатный набор командлетов (часто называемых также AD cmdlets или QAD cmdlets), доступный с сайта http://www.quest.com/activeroles_server/arms.aspx.

А для создания пользователя команду New-QADUser, полный синтаксис команды доступен в wiki: http://wiki.powergui.org/index.php/New-QADUser

$Domen = "MyServerAD" #Read-Host "Введите адресс контролера"
$User = "MyUser" #read-host "Введите логин"
$Password =read-host "Введите пароль" -AsSecureString;

#Подключаемся к AD
Connect-QADService -Service $Domen -ConnectionAccount $User  -ConnectionPassword $Password;

#Создаём подключение к серверу БД
$SQLConnection = new-object System.Data.SqlClient.SqlConnection("Data Source='MyServerBD';User='MyUser';password='MyPassword';")
#Запрос к таблице с Юзерами
$Query="select * from Test.dbo.Users"
$SQLConnection.Open()
$SQLCommand = New-Object System.Data.SqlClient.SqlCommand($Query, $SQLConnection)

$SQLAdapter = New-Object System.Data.SqlClient.SqlDataAdapter($SQLCommand)

$DataSet = New-Object System.Data.DataSet;
$SQLAdapter.Fill($DataSet);
$DataTable=New-Object System.Data.DataTable
$DataTable=$DataSet.Tables[0]
$rdr=$SQLCommand.ExecuteReader()

#В цикле по всему рекордсету перебераю записи с юзерами
While($rdr.Read())
{
#Выводим логин
Write-Host $rdr[0]
#Создаём пользователя в AD
New-QADUser -Name $rdr[0] -ParentContainer "MyServerAD.com/Users"  -SamAccountName $rdr[0] -UserPassword $rdr[1]
}
#Закрываем подключение к Серверу БД
$SQLConnection.Close();
#Отключаемся от AD
Disconnect-QADService;

Скрипт достаточно примитивный, но работает и если его довести до ума, то можно в AD экспортировать и другую информацию о пользователе.

Ранее я писал, как с помощью PowerShell создать группы пользователей AD: http://www.t-sql.ru/post/ADGroupsPoSh.aspx

Tags: , , ,

PowerShell | SQL Server

Скрипт выгрузки данных в Inserts-файл

by Alexey Knyazev 25. января 2010 21:19

В одной из своих заметок в блоге я публиковал, как можно с помощью PowerShell заскриптовать все объекты той или иной БД на сервере баз данных (Скриптуем объекты БД (PoSh) ), а на днях в коментариях в этому скрипту появился вопрос, как заскриптовать сами данные, а не только "скелет" базы.

Но прежде чем показать скрипт на PowerShell, перечислю другие возможные способы реализации данной задачи

Во первых - подумайте, действительно ли вам необходимы данные в виде файла, не проще ли (а самое главное правильнее) сделать Бэкап базы

Второй вариант - это T-SQL скрипт, т.к. в сети легко найти подобное решение, то я не стал изобретать велосипед, а предлагаю воспользоваться скриптом Narayana Vyas Kondreddi: SQL Server 2000 либо SQL Server 2005/2008

Ещё одно решение - стандартный клиент для работы с SQL Server 2005 и выше: SSMS (Microsoft SQL Server Management Studio). Для SSMS2005 - это надстройка (ADD-IN) Generate Insert statements from resultsets, tables or database из пакета дополнительных надстроек http://www.ssmstoolspack.com/

При этом в SSMS2008 подобная надстройка добавлена: Tasks->Generate Scripts..., а дальше в Wizard`e отметить, что в скрипт мы хотим включить не только объекты БД, но и данные.

Ну и вариант на PowerShell с использованием SMO:

$server=Read-Host "Укажите имя сервера БД"
$database=Read-Host "Имя БД"
$output_file=Read-Host "Вывести результат в файл (укажите имя файла)"

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

$srv = New-Object "Microsoft.SqlServer.Management.SMO.Server" $server
$db = New-Object ("Microsoft.SqlServer.Management.SMO.Database")
$tbl = New-Object ("Microsoft.SqlServer.Management.SMO.Table")
$scripter = New-Object ("Microsoft.SqlServer.Management.SMO.Scripter") ($server)

$db = $srv.Databases[$database]

$scripter.Options.ScriptSchema = $true;
$scripter.Options.ScriptData = $true;
$scripter.Options.DriAll = $true
$scripter.Options.DriAllConstraints = $true
$scripter.Options.DriAllKeys = $true
$scripter.Options.DriChecks = $true
$scripter.Options.DriClustered = $true
$scripter.Options.DriDefaults = $true
$scripter.Options.DriForeignKeys = $true
$scripter.Options.DriIncludeSystemNames = $true
$scripter.Options.DriIndexes = $true
$scripter.Options.DriNonClustered = $true
$scripter.Options.DriPrimaryKey = $true
$scripter.Options.DriUniqueKeys = $true

$scripter.Options.AppendToFile =$true

$scripter.Options.FileName = $output_file
$scripter.Options.ToFileOnly = $true

foreach ($tbl in $db.Tables)
{
foreach ($s in $scripter.EnumScript($tbl.Urn)) { write-host $s }
}

Список пар-ов ScriptingOptions, можно посмотреть на MSDN http://msdn.microsoft.com/ru-ru/library/microsoft.sqlserver.management.smo.scriptingoptions_members.aspx

Tags: , , , , ,

PowerShell | SQL Server

С нoвым гoдом

by Alexey Knyazev 31. декабря 2009 21:05

С новым, 2010 годом, коллеги!!! Здоровья, счастья, любви и конечно же новых побед! С праздником!

Tags: ,

PowerShell | SQL Server

Job Activity Monitor (PоSh)

by Alexey Knyazev 12. ноября 2009 19:59

Продолжая тему скриптов на PowerShell в помощь администраторам БД, предлагаю вариант Job Activity Monitor(Журнал выполнения заданий) на PowerShell.

Так как задания SQL Server Agent чаще всего выполняются по расписанию, то, скорее всего, вам потребуется просматривать историю их выполнения, например для того, чтобы убедиться, что они выполняются успешно и каких-либо проблем не возникает.

Год назад я публиковал вариант в виде Windows-приложения (http://www.itcommunity.ru/blogs/mssql/archive/2008/12/04/40235.aspx), теперь более лёгкий и гибкий скрипт.

#Строка коннекции к БД (в данном случае с Windows-авторизацией)
$ConnectionString="Data Source=(local);Trusted_Connection=yes;Integrated Security=SSPI;"

#Ниже СКЛ-авторизация (для примера)
#"$ConnectionString="Data Source=(local);User=UserName;password=MyPassword;"

[void][reflection.assembly]::LoadWithPartialName("System.Data.Sql")
[void][reflection.assembly]::LoadWithPartialName("System.Data.SqlClient")
[void][reflection.assembly]::LoadWithPartialName("System.Windows.Forms")

#Основной запрос к Серверу БД, для получения списка Job`ов
$Query=
"SELECT * FROM
(SELECT top 1 with ties
t1.name, t1.originating_server,
last_run_outcome=case t1.last_run_outcome
when 0 then 'Failed'
when 1 then 'Succeeded'
when 3 then 'Canceled'
when 5 then 'Unknown'
end,
enabled=case t1.enabled when 0 then 'NO' else 'YES' end,
current_execution_status=case t1.current_execution_status
when 1 then 'Executing'
when 2 then 'Waiting For Thread'
when 3 then 'Between Retries'
when 4 then 'Idle'
when 5 then 'Suspended'
when 6 then '[obsolete]'
when 7 then 'PerformingCompletion'
end,
t2.last_executed_step_date,
t2.next_scheduled_run_date,
t1.job_id
FROM OPENROWSET('SQLOLEDB','$ConnectionString','EXEC msdb..sp_help_job') t1
INNER JOIN msdb.dbo.sysjobactivity t2
ON t1.job_id=t2.job_id
ORDER BY row_number() over (partition by t1.job_id order by t2.job_history_id desc)
) t ORDER BY name
"

#Создаём коннекцию
$SQLConnection = new-object System.Data.SqlClient.SqlConnection($ConnectionString)
#Идентификатор сессии, изначально=0
$jobid=0

#Функция для заполнения таблицы Job`ов
function GetJobs
{
$SQLConnection.Open()
$SQLCommand = New-Object System.Data.SqlClient.SqlCommand($Query, $SQLConnection)
$SQLAdapter = New-Object System.Data.SqlClient.SqlDataAdapter($SQLCommand)
$DataSet = New-Object System.Data.DataSet;
$SQLAdapter.Fill($DataSet);
$DataTable=New-Object System.Data.DataTable
$DataTable=$DataSet.Tables[0]
$reader=$SQLCommand.ExecuteReader()

$ListView.Items.Clear()
while ($reader.Read())
{
$item=new-object Windows.Forms.ListViewItem
$item.Text=$reader[0]
[void]$item.SubItems.Add($reader[1])
[void]$item.SubItems.Add($reader[2])
[void]$item.SubItems.Add($reader[3])
[void]$item.SubItems.Add($reader[4])
[void]$item.SubItems.Add($reader[5].ToString())
[void]$item.SubItems.Add($reader[6].ToString())
[void]$item.SubItems.Add($reader[7].ToString())

#Подкрашиваем красным строки у которых Job не выполнился
if ($reader[2] -eq "Failed")
{ $item.ForeColor="Red"}
[void]$ListView.Items.Add($item)
}

$SQLConnection.Close()
$ListView.Refresh()
#Время последнего считывания данных из БД потаймеру
$Time.Text="Last Update: $((Get-Date).ToString())"
}

#Функция для заполнения таблицы Step`ов
function GetHistory ($id)
{
$QueryHistory="SELECT
CASE run_date WHEN 0 THEN NULL ELSE
    convert(datetime,
            stuff(stuff(cast(run_date as nchar(8)), 7, 0, '-'), 5, 0, '-') + N' ' +
            stuff(stuff(substring(cast(1000000 + run_time as nchar(7)), 2, 6), 5, 0, ':'), 3, 0, ':'),
            120) END AS [RunDate],
step_id, step_name,
run_status=case run_status
when 0 then 'Failed'
when 1 then 'Succeeded'
when 2 then 'Retry (step only)'
when 3 then 'Canceled'
when 4 then 'In-progress message'
when 5 then 'Unknown'
end, message
FROM msdb.dbo.sysjobhistory
WHERE job_id='$id'
ORDER BY Instance_ID DESC"

$SQLConnection.Open()
$SQLCommand = New-Object System.Data.SqlClient.SqlCommand($QueryHistory, $SQLConnection)
$SQLAdapter = New-Object System.Data.SqlClient.SqlDataAdapter($SQLCommand)
$DataSet = New-Object System.Data.DataSet;
$SQLAdapter.Fill($DataSet);
$DataTable=New-Object System.Data.DataTable
$DataTable=$DataSet.Tables[0]
$reader=$SQLCommand.ExecuteReader()

while ($reader.Read())
{
$item=new-object Windows.Forms.ListViewItem
$item.Text=$reader[0].ToString()
[void]$item.SubItems.Add($reader[1])
[void]$item.SubItems.Add($reader[2])
[void]$item.SubItems.Add($reader[3])
[void]$item.SubItems.Add($reader[4])

#StepID=0 выделяем жирным
if ($reader[1] -eq "0")
{
$titleFont = new-object System.Drawing.Font($this.Font,
[System.Drawing.FontStyle]::Bold)
$item.Font=$titleFont
}
#Подкрашиваем красным строки у которых Шаг закончился неудачей
if ($reader[3] -eq "Failed")
{
$item.ForeColor="Red"
}
[void]$ListViewHistory.Items.Add($item)
}
$SQLConnection.Close()
$ListViewHistory.Refresh()
}

$timer = new-object Windows.Forms.Timer
#Значение (в мс), через которое автоматически обновляется таблица (в данном случае раз в 60 секунд)
$timer.Interval=60000

#Создаём форму
$form = new-object Windows.Forms.Form
$form.Text = "Job Activity Monitor"
$form.WindowState="Maximized"
$form.startposition = "CenterScreen"
$form.autosize = 0 

#add a PanelJobs
$PanelJobs = new-object Windows.Forms.Panel
$PanelJobs.Location = New-Object System.Drawing.Size(0,0)
$PanelJobs.Dock="Fill"

#add a PanelSteps
$PanelSteps = new-object Windows.Forms.Panel
$PanelSteps.Location = New-Object System.Drawing.Size(0,200)
$PanelSteps.Height=300
$PanelSteps.Dock="Bottom"

#add a Scroll
$Scroll = new-object Windows.Forms.Splitter
$Scroll.Location = New-Object System.Drawing.Size(0,190)
$Scroll.Dock="Bottom"

#add a ListViewHistory
$ListViewHistory = new-object Windows.Forms.ListView
$ListViewHistory.Location = New-Object System.Drawing.Size(0,0)
$ListViewHistory.Dock="Fill"
$ListViewHistory.FullRowSelect="True"
$ListViewHistory.View="Details"
$ListViewHistory.Columns.Add("Date", 140)
$ListViewHistory.Columns.Add("Step ID", 60)
$ListViewHistory.Columns.Add("Step Name", 120)
$ListViewHistory.Columns.Add("Status", 80)
$ListViewHistory.Columns.Add("Message", 500)

#add a ListViewJobs
$ListView = new-object Windows.Forms.ListView
$ListView.Location = New-Object System.Drawing.Size(0,0)
$ListView.Dock="Fill"
$ListView.FullRowSelect="True"
$ListView.View="Details"
$ListView.Columns.Add("Name", 150)
$ListView.Columns.Add("Server", 100)
$ListView.Columns.Add("Last_Run_Outcome", 120)
$ListView.Columns.Add("Enabled", 80)
$ListView.Columns.Add("Status", 100)
$ListView.Columns.Add("Last Run", 120)
$ListView.Columns.Add("Next Run", 120)

#Выводим Шаги у выбранного Job`a
$ListView.Add_ItemSelectionChanged({
$ListViewHistory.Items.Clear()
$jobid=$this.items[$_.itemindex].SubItems[7].Text
GetHistory $jobid
}
)

#add a statusStrip
$statusStrip = new-object System.Windows.Forms.StatusStrip
$Time = new-object System.Windows.Forms.ToolStripStatusLabel
$Time.Text="Last Update: "
[void]$statusStrip.Items.add($Time)

#По таймеру обновляем табличку
$timer.add_Tick({GetJobs})
$timer.Start()

$form.controls.add($scroll)
$form.controls.add($PanelJobs)
$PanelSteps.controls.add($ListViewHistory)
$form.controls.add($PanelSteps)
$PanelJobs.controls.add($ListView)
$form.controls.add($statusStrip)

GetJobs
$form.Add_Shown({$form.Activate()})
$form.ShowDialog()

Tags: , , , ,

PowerShell | SQL Server

Мониторинг блокировок на PowerShell

by Alexey Knyazev 10. ноября 2009 19:54

Блокирование (LOCK) Каждая транзакция запрашивает блокировку разных типов ресурсов, например строк, страниц или таблиц, от которых эта транзакция зависит.

Блокировка не дает другим транзакциям изменять ресурсы, чтобы избежать ошибок в транзакции, запросившей блокировку. Каждая транзакция освобождает свои блокировки, если больше не зависит от блокируемого ресурса.

Блокировки (особенно взаимоблокировки) - головная боль любого администратора, для их отслеживания написано не мало инструментов, в качестве примера работы с PowerShell предлагаю свой вариант утилиты для мониторинга блокировок.

#Строка коннекции к БД (в данном случае с Windows-авторизацией)
$ConnectionString="Data Source='(local)';Integrated Security=SSPI;"

#Ниже СКЛ-авторизация (для примера)
#Data Source='(local)';User='Login';password='Password';")

#Основной запрос к Серверу БД, для получения списка процессов
$Query=
"
select
spid,
blocked,
db_name(dbid) db,
cmd,
status,
hostname,
program_name,
loginame,
waittime, cpu, physical_io, MemUsage,
isnull((select text from sys.dm_exec_sql_text(sql_handle)),'') sql
from master.dbo.sysprocesses
--where blocked!=0
order by spid
"

#Создаём коннекцию
$SQLConnection = new-object System.Data.SqlClient.SqlConnection($ConnectionString)
#Идентификатор сессии, изначально=0
$spid=0

#Функция для заполнения таблицы
function GetProcesses
{
$SQLConnection.Open()
$SQLCommand = New-Object System.Data.SqlClient.SqlCommand($Query, $SQLConnection)
$SQLAdapter = New-Object System.Data.SqlClient.SqlDataAdapter($SQLCommand)
$DataSet = New-Object System.Data.DataSet;
$SQLAdapter.Fill($DataSet);
$DataTable=New-Object System.Data.DataTable
$DataTable=$DataSet.Tables[0]
$reader=$SQLCommand.ExecuteReader()

$ListView.Items.Clear()
while ($reader.Read())
{
$item=new-object Windows.Forms.ListViewItem
$item.Text=$reader[0]
[void]$item.SubItems.Add($reader[1])
[void]$item.SubItems.Add($reader[2])
[void]$item.SubItems.Add($reader[3])
[void]$item.SubItems.Add($reader[4])
[void]$item.SubItems.Add($reader[5])
[void]$item.SubItems.Add($reader[6])
[void]$item.SubItems.Add($reader[7])
[void]$item.SubItems.Add($reader[8])
[void]$item.SubItems.Add($reader[9])
[void]$item.SubItems.Add($reader[10])
[void]$item.SubItems.Add($reader[11])
[void]$item.SubItems.Add($reader[12])
#Подкрашиваем красным строки у которых blocked<>0
if ($reader[1] -ne 0)
{ $item.ForeColor="Red"}
[void]$ListView.Items.Add($item)
}

$SQLConnection.Close()
$ListView.Refresh()
#Время последнего считывания данных из БД потаймеру
$Time.Text="Last Update: $((Get-Date).ToString())"
}

#Функция удаления сессии
function KillProcess ($id)
{
$QueryKill="kill $id"

$SQLConnection.Open()
$SQLCommand = New-Object System.Data.SqlClient.SqlCommand($QueryKill, $SQLConnection)
$SQLCommand.ExecuteNonQuery()
$SQLConnection.Close()
}

[void][reflection.assembly]::LoadWithPartialName("System.Data.Sql")
[void][reflection.assembly]::LoadWithPartialName("System.Data.SqlClient")
[void][reflection.assembly]::LoadWithPartialName("System.Windows.Forms")
$timer = new-object Windows.Forms.Timer
#Значение (в мс), через которое автоматически обновляется таблица (в данном случае раз в 10 секунд)
$timer.Interval=10000

#Создаём форму
$form = new-object Windows.Forms.Form
$form.Text = "SQL Server Locks"
$form.WindowState="Maximized"
$form.startposition = "CenterScreen"
$form.autosize = 0 

#add a PanelLocs
$PanelLocks = new-object Windows.Forms.Panel
$PanelLocks.Location = New-Object System.Drawing.Size(0,0)
$PanelLocks.Dock="Fill"

#add a PanelView
$PanelView = new-object Windows.Forms.Panel
$PanelView.Location = New-Object System.Drawing.Size(0,200)
$PanelView.Height=100
$PanelView.Dock="Bottom"

#add a Scroll
$Scroll = new-object Windows.Forms.Splitter
$Scroll.Location = New-Object System.Drawing.Size(0,190)
$Scroll.Dock="Bottom"

#add a PanelButton
$PanelButton = new-object Windows.Forms.Panel
$PanelButton.Location = New-Object System.Drawing.Size(0,0)
$PanelButton.Width=100
$PanelButton.BorderStyle="Fixed3D"
$PanelButton.Dock="Right"

# add a TextBoxResult
$TextBoxResult = new-object Windows.Forms.TextBox
$TextBoxResult.Location = New-Object System.Drawing.Size(0,0)
$TextBoxResult.Multiline="true"
$TextBoxResult.Dock="Fill"
$TextBoxResult.ScrollBars="Vertical"

#add a button
$button = new-object Windows.Forms.button
$button.Location = New-Object System.Drawing.Size(5,5)
$button.text = "Kill"
$button.width = 90
#Удаляем сессию по нажатию на кнопку "Kill"
$button.add_click({
KillProcess $spid
GetProcesses
})

# add a TreeView
$ListView = new-object Windows.Forms.ListView
$ListView.Location = New-Object System.Drawing.Size(0,0)
$ListView.Dock="Fill"
$ListView.FullRowSelect="True"
$ListView.View="Details"
$ListView.Columns.Add("SPID", 50)
$ListView.Columns.Add("Blocked", 50)
$ListView.Columns.Add("DB", 60)
$ListView.Columns.Add("CMD", 100)
$ListView.Columns.Add("Status", 80)
$ListView.Columns.Add("HostName", 80)
$ListView.Columns.Add("ProgramName", 120)
$ListView.Columns.Add("LoginName", 100)
$ListView.Columns.Add("WaitTime", 80)
$ListView.Columns.Add("CPU", 80)
$ListView.Columns.Add("Physical IO", 80)
$ListView.Columns.Add("MemUsage", 80)
$ListView.Columns.Add("SQL", 200)

#Выводим текст запроса в выбранной сессии в таблице
$ListView.Add_ItemSelectionChanged({
$TextBoxResult.Clear()
$TextBoxResult.Text=$this.items[$_.itemindex].SubItems[12].Text
$spid=$this.items[$_.itemindex].Text
}
)

#add a statusStrip
$statusStrip = new-object System.Windows.Forms.StatusStrip
$Time = new-object System.Windows.Forms.ToolStripStatusLabel
$Time.Text="Last Update: "
[void]$statusStrip.Items.add($Time)

#По таймеру обновляем табличку
$timer.add_Tick({GetProcesses})
$timer.Start()

$form.controls.add($scroll)
$form.controls.add($PanelView)
$PanelView.controls.add($PanelButton)
$PanelView.controls.add($TextBoxResult)
$PanelButton.controls.add($button)
$form.controls.add($PanelLocks)
$PanelLocks.controls.add($ListView)
$form.controls.add($statusStrip)

GetProcesses
$form.Add_Shown({$form.Activate()})
$form.ShowDialog()

Tags: , , , ,

PowerShell | SQL Server

Чистим сервер БД от учёток отключенных в AD (PoSh)

by Alexey Knyazev 24. июня 2009 17:03

На днях пришлось навести порядок на нескольких старых серверах БД. Суть проблемы: в АД более 9500 учётных записей, активных не более 30% (остальные disabled).

Исторически сложилось так, что на серверах БД остались "висеть" и ряд учётных записей людей, которые покинули стены родного предприятия. В условия кризиса и не минуемой текучки персонала, скрипт написанный на PowerShell облегчит многим жизнь, в том числе и мне.

 

Для работы с AD я использую набор командлетов (часто называемых также AD cmdlets или QAD cmdlets), доступный с сайта http://www.quest.com/activeroles_server/arms.aspx.

$Domain = Read-Host "Введите адресс контролера"
$User = Read-Host "Введите логин"
$Password = Read-Host "Введите пароль" -AsSecureString;

#Функция очистки сервера БД от пользователей, которые в AD Disabled=TRUE

function DeleteLoginFromMSSQL ($Login)
{
#Подставляем к логину свой домен
$Login="Domain\$Login"
#Подключаемся к серверу, который чистим от учёток (в данном случае использую Windows-авторизацию)
$SQLConnection = new-object System.Data.SqlClient.SqlConnection(("Data Source='MyServerDB';Integrated Security=SSPI"))
#Сам запрос на очистку
$SQLQuery =
"DECLARE @Login sysname " +
" SET @Login='"+$Login+
#Чистим только если текущая отключенная учётка фигурирует на нашем сервере БД
"'IF EXISTS (SELECT * FROM SYS.SERVER_PRINCIPALS WHERE name=@Login) "+
"BEGIN" +
"DECLARE @str VARCHAR(255) "+
#Для более корректной очистки учёток, сперва удалим соответствующих им юзеров из всех баз
"SET @str=' "+
"USE ?; " +
"DECLARE @UserName sysname "+
"SELECT @UserName=t1.name FROM SYS.DATABASE_PRINCIPALS t1 INNER JOIN SYS.SERVER_PRINCIPALS t2 "+
"ON t1.sid=t2.sid where t2.name='''+@Login+''' "+
"IF @UserName IS NOT NULL "+
"EXECUTE sp_revokedbaccess @UserName; ' "+
#Вместо курсора по базам использую недокументированную функцию SP_MSFOREACHDB
"EXEC SP_MSFOREACHDB @str "+
#Удаляю саму учётку
"EXEC ('DROP LOGIN ['+@Login+']') " +
"END"

#Далее подключаюсь к серверу БД и выполняю запрос
$SQLConnection.Open()
$SQLCommand = New-Object System.Data.SqlClient.SqlCommand($SQLQuery, $SQLConnection)
$SQLCommand.ExecuteNonQuery()
$SQLConnection.Close()
}

#Подключаемся к АД
Connect-QADService -Service $Domain -ConnectionAccount $User  -ConnectionPassword $Password;

#Пробегаем по всем отключенным пользователям из АД и вызываем функцию созданную выше
Get-QADUser -Disabled | foreach {DeleteLoginFromMSSQL $_.LogonName} 

#Отключение от АД
Disconnect-QADService;

 

 

Tags: , ,

PowerShell | SQL Server

Скрипт создания групп пользователей в AD (PoSh)

by Alexey Knyazev 14. мая 2009 16:06

Часто, в моей работе необходимо создавать группы пользователей в AD, добавлять туда десятки пользователей. А этим группам давать те или иные права на работу с серверами БД.

Для этого я написал небольшой скриптик на PowerShell, который создаёт в Active Directory группы из списка указанного в текстовом файле и заливает в эти группы пользователей, список которых так же подаётся на входе в виде текстового файла.

 

$Domain = Read-Host "Введите адресс контролера";

$User = Read-Host "Введите логин"; 

$Password = Read-Host "Введите пароль" -AsSecureString;

 

#Подключаемся к контроллеру

Connect-QADService -Service $Domain -ConnectionAccount $User  -ConnectionPassword $Password;

 

#Считываем список групп из текстового файла “C:\Groups.txt” 

$GrList = Get-Content "C:\Groups.txt"

foreach ($i in $GrList)

{

$gr=Get-QADGroup -DisplayName $i;

if ($gr  -eq  $null)

{

#Создаём группы в цикле, если их не было в AD. 

#Контейнер куда создаются группы=’DC=SQLServerGroups,DC=SERVERNAME,DC=COM’

New-QADGroup -ParentContainer "DC=SQLServerGroups,DC=SERVERNAME,DC=COM" -name $i -DisplayName $i -samAccountName $i;

"Создали новую группу="+$i;

}

else

{ 

"Группа была="+$i;

}

#Считываем список пользователей из текстовых файлов, где имя файла=”C:\имени группы”

$UserList = Get-Content "C:\$i.txt"

foreach ($j in $UserList)

{

#Так как у меня список юзеров хранится без указания домена, 

#то префикс подставляю к коде, где Domain - имя вашего домена

add-QADGroupMember -identity $i -member "Domain\$j"

}

}

#Отключаемся от контроллера

disconnect-QADService;

Tags: , , ,

PowerShell | SQL Server

Получение списка SQL Server`ов (PowerShell)

by Alexey Knyazev 13. мая 2009 15:57

Есть много способов получить список SQL Server`ов в вашей сети, но меня больше интересуют скрипты на PowerShell (PoSh).

Предлагаю 3 небольших способа:

********

#1 способ (используем SQLCMD):
SQLCMD -L | Out-GridView

 

#2 способ (используем SMO):
[System.Reflection.Assembly]::LoadWithPartialName('Microsoft.SqlServer.Smo') | Out-Null
$SmoApplication = [Microsoft.SqlServer.Management.Smo.SmoApplication]
$dt= $SmoApplication::EnumAvailableSqlServers($false)
$dt.DefaultView | Out-GridView

 

#3 способ
$dt={[System.Data.Sql.SqlDataSourceEnumerator]::Instance.GetDataSources()}
$dt.DefaultView | Out-GridView

 

 

Во всех 3-х способах я вывожу результат в GridView (PowerShell v2).

Tags: ,

PowerShell | SQL Server

Powered by BlogEngine.NET 1.6.0.0
Все права защищены © T-SQL.RU | Alexey Knyazev 2008-2010

MVP:SQL