Добро пожаловать в форум, Guest  >>   Войти | Регистрация | Поиск | Правила | В избранное | Подписаться
Все форумы / Microsoft SQL Server Новый топик    Ответить
 PowerShell - Как академично получить объект Machine?  [new]
Жмурик
Member

Откуда: Оттуда
Сообщений: 382
Приведенный ниже скрипт выдает списки БД всех SQL Server инстансов и работает корректно:

import-module SQLPS -DisableNameChecking
$mach = get-childitem sql # $mach is a Microsoft.SqlServer.Management.PowerShell.Extensions.Machine
foreach ($insts in $mach.Servers) {
foreach ($inst in $insts.Values) {
$instName = $inst.MachineName
if ($inst.InstanceName -ne "DEFAULT") { $instName += "\" + $inst.InstanceName }
$srv = new-object('Microsoft.SqlServer.Management.Smo.Server') $instName
foreach ($db in $srv.Databases) { write $dbName }
}
}

Но мне хотелось бы для доступа к объекту типа Machine использовать
  • не "диски:" (кмдлет выделен красным), чтобы не зависеть от текщего Location,
  • а явное создание экземпляров (кмдлет выделен зеленым).

    Помогите?
  • 11 дек 14, 17:20    [16984790]     Ответить | Цитировать Сообщить модератору
     Re: PowerShell - Как академично получить объект Machine?  [new]
    andrey odegov
    Member

    Откуда:
    Сообщений: 473
    Для "красного"-укажите sqlserver-провайдер явно:
    $mach = get-childitem sqlserver:sql
    
    11 дек 14, 22:07    [16985775]     Ответить | Цитировать Сообщить модератору
     Re: PowerShell - Как академично получить объект Machine?  [new]
    andrey odegov
    Member

    Откуда:
    Сообщений: 473
    м.б. так?
    ls sqlserver:\sql|%{$_.servers.values}|%{$_.domainroot}|%{$_.databases}|%{$_.name}
    
    или так
    foreach($mach in ls sqlserver:\sql){
     foreach($svr in $mach.servers.values){
      foreach($dr in $svr.DomainRoot){
       foreach($db in $dr.Databases){
        write-host $db.name
       }
      }
     }
    }
    
    11 дек 14, 22:40    [16985880]     Ответить | Цитировать Сообщить модератору
     Re: PowerShell - Как академично получить объект Machine?  [new]
    Жмурик
    Member

    Откуда: Оттуда
    Сообщений: 382
    andrey odegov,

    Спа-си-бо! Это оно!
    Я уже думал, никто мне не поможет, даже RTFM.

    Вообще-то я не в восторге от такой неочевидности (я имею в виду с первого раза) решений. Но это уже совсем другая история...
    12 дек 14, 11:21    [16987393]     Ответить | Цитировать Сообщить модератору
     Re: PowerShell - Как академично получить объект Machine?  [new]
    Жмурик
    Member

    Откуда: Оттуда
    Сообщений: 382
    Хотя...
    foreach($mach in ls sqlserver:\sql)
    
    Get-ChildItem, завуалированное под ls, говорит, что это все те же "Диски:"

    И, хотя все работает, хотелось бы альтернативного способа без провайдеров.
    12 дек 14, 17:30    [16990579]     Ответить | Цитировать Сообщить модератору
     Re: PowerShell - Как академично получить объект Machine?  [new]
    andrey odegov
    Member

    Откуда:
    Сообщений: 473
    поясните, пожалуйста, примером.
    12 дек 14, 19:16    [16991057]     Ответить | Цитировать Сообщить модератору
     Re: PowerShell - Как академично получить объект Machine?  [new]
    Жмурик
    Member

    Откуда: Оттуда
    Сообщений: 382
    Ну например в Вашем примере первый foreach обходит диск sqlserver: (вернее одну его папку).
    А остальные три foreach обходят уже коллекции объектов (.values, .DomainRoot и .Databases).

    andrey odegov
    foreach($mach in ls sqlserver:\sql){
     foreach($svr in $mach.servers.values){
      foreach($dr in $svr.DomainRoot){
       foreach($db in $dr.Databases){
        write-host $db.name
       }
      }
     }
    }
    


    Хотелось бы заменить foreach($mach in ls sqlserver:\sql), то есть обход папки диска (предоставляемого провайдером),
    на обход какого-нибудь к примеру new Object(...).
    15 дек 14, 14:38    [16999012]     Ответить | Цитировать Сообщить модератору
     Re: PowerShell - Как академично получить объект Machine?  [new]
    Жмурик
    Member

    Откуда: Оттуда
    Сообщений: 382
    Другими словами, я не хочу пользоваться провайдерами дисков, и не хочу пользоваться никакими текущими контекстами. А хочу оставаться в рамках ООП.
    15 дек 14, 14:59    [16999156]     Ответить | Цитировать Сообщить модератору
     Re: PowerShell - Как академично получить объект Machine?  [new]
    guest123456
    Guest
    Жмурик,

    (Get-ItemProperty "HKLM:\SOFTWARE\Microsoft\Microsoft SQL Server").InstalledInstances
    и затем подсовывать полученное конструктору Smo.Server - так что ли?
    15 дек 14, 17:30    [17000363]     Ответить | Цитировать Сообщить модератору
     Re: PowerShell - Как академично получить объект Machine?  [new]
    Жмурик
    Member

    Откуда: Оттуда
    Сообщений: 382
    Напрягает обращение к реестру напрямую.
    И напрягает HKLM: - это тоже диск, только другого провайдера.

    Нельзя ли создать именно Microsoft.SqlServer.Management.PowerShell.Extensions.Machine?

    Спинным мозгом чувствую, существует академический способ.
    15 дек 14, 17:43    [17000406]     Ответить | Цитировать Сообщить модератору
     Re: PowerShell - Как академично получить объект Machine?  [new]
    andrey odegov
    Member

    Откуда:
    Сообщений: 473
    если выполняется служба SQL Server Browser, то так:
    [void][reflection.assembly]::LoadWithPartialName('Microsoft.SqlServer.Smo')
    [Microsoft.SqlServer.Management.Smo.SmoApplication]::EnumAvailableSqlServers($true)|%{
     new-object microsoft.sqlserver.management.smo.server $_.name
    }|select -expand databases|select -expand name
    
    16 дек 14, 00:47    [17001913]     Ответить | Цитировать Сообщить модератору
     Re: PowerShell - Как академично получить объект Machine?  [new]
    Жмурик
    Member

    Откуда: Оттуда
    Сообщений: 382
    andrey odegov,

    Да, спасибо, работает!
    Правда пришлось перевести в удобочитаемый вид:
    $load = [reflection.assembly]::LoadWithPartialName('Microsoft.SqlServer.Smo')
    $smoApp = [Microsoft.SqlServer.Management.Smo.SmoApplication]
    $servers = $smoApp::EnumAvailableSqlServers($true)
    
    foreach($inst in $servers)
    {
        $instName = $inst.Name
        if ($inst.Instance -ne '')
            { $instName += "\" + $inst.Instance }
        $srv = new-object microsoft.sqlserver.management.smo.server $inst.
        foreach($db in $srv.Databases)
           { $db.Name }
    }
    
    Теперь получаемые объекты содержат гораздо больше информации о серверах и базах...

    П.С. Нашел в сети еще более академический способ
    Add-Type -AssemblyName "Microsoft.SqlServer.Smo"
    
    но он официально глючит на одиночном инстансе SQL 2012, что делает его непригодным. Глюк лечится указанием версии и ключа строгой сборки, что тоже не академично.

    Эта ложка дегтя обычно умалчивается в хвалебных статьях про PowerShell.
    Да и какой же это скриптовый язык к чepтoвoй мaтepи, если приходится обращаться к статическим методам классов. Должен ли вообще админ, на кого ориентирован PS, что-то знать о сборках, классах и статических членах?
    Ну ладно, сорри, это эмоции. Что имеем, то имеем, лучше все равно нет ничего некомпилируемого...
    16 дек 14, 03:23    [17002036]     Ответить | Цитировать Сообщить модератору
    Все форумы / Microsoft SQL Server Ответить