Подтвердить что ты не робот

Как загрузить сборки в PowerShell?

Следующий код PowerShell

#Get a server object which corresponds to the default instance
$srv = New-Object -TypeName Microsoft.SqlServer.Management.SMO.Server
... rest of the script ...

Выдает следующее сообщение об ошибке:

New-Object : Cannot find type [Microsoft.SqlServer.Management.SMO.Server]: make sure 
the assembly containing this type is loaded.
At C:\Users\sortelyn\ ... \tools\sql_express_backup\backup.ps1:6  char:8
+ $srv = New-Object -TypeName Microsoft.SqlServer.Management.SMO.Server
+        ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo          : InvalidType: (:) [New-Object], PSArgumentException
+ FullyQualifiedErrorId : TypeNotFound,Microsoft.PowerShell.Commands.NewObjectCommand

Каждый ответ в Интернете пишет, что мне нужно загрузить сборку - ну, конечно, я могу прочитать это из сообщения об ошибке:-) - вопрос:

Как вы загружаете сборку и выполняете работу script?

4b9b3361

Ответ 1

LoadWithPartialName устарел. Рекомендуемым решением для PowerShell V3 является использование командлета Add-Type, например:

Add-Type -Path 'C:\Program Files\Microsoft SQL Server\110\SDK\Assemblies\Microsoft.SqlServer.Smo.dll'

Существует несколько разных версий, и вы можете выбрать конкретную версию.: -)

Ответ 2

[System.Reflection.Assembly]::LoadWithPartialName("Microsoft.SqlServer.Smo")

Ответ 3

Большинство людей уже знают, что System.Reflection.Assembly.LoadWithPartialName устарел, но оказывается, что Add-Type -AssemblyName Microsoft.VisualBasic не ведет себя намного лучше, чем LoadWithPartialName:

Вместо того, чтобы пытаться проанализировать ваш запрос в контексте ваша система, [Add-Type], смотрит на статическую внутреннюю таблицу, чтобы перевести "partial name" на "полное имя".

Если ваше "частичное имя" не отображается в их таблице, ваш script будет потерпеть неудачу.

Если на вашем компьютере установлено несколько версий сборки компьютер, нет интеллектуального алгоритма выбора между ними. Вы получите тот, который появляется в их таблице, вероятно более старый, устаревший.

Если версии, которые вы установили, новее, чем устаревшие в таблице ваш script завершится с ошибкой.

Add-Type не имеет интеллектуального парсера "частичных имен", например .LoadWithPartialNames.

Что Microsoft говорит, что вы на самом деле должны делать, это примерно так:

Add-Type -AssemblyName 'Microsoft.VisualBasic, Version=10.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a'

Или, если вы знаете путь, что-то вроде этого:

Add-Type -Path 'C:\WINDOWS\Microsoft.Net\assembly\GAC_MSIL\Microsoft.VisualBasic\v4.0_10.0.0.0__b03f5f7f11d50a3a\Microsoft.VisualBasic.dll'

Это длинное имя для сборки известно как сильное имя , которое уникально для версии и сборки, а также иногда называется полным именем.

Но это оставляет пару вопросов без ответа:

  • Как определить сильное имя того, что на самом деле загружается в моей системе с заданным частичным именем?

    [System.Reflection.Assembly]::LoadWithPartialName($TypeName).Location; [System.Reflection.Assembly]::LoadWithPartialName($TypeName).FullName;

  • Если я хочу, чтобы мой script всегда использовал определенную версию .dll, но я не могу быть уверенным в том, где он установлен, как определить, какое сильное имя из .dll?

    [System.Reflection.AssemblyName]::GetAssemblyName($Path).FullName;

  • Если я знаю сильное имя, как определить путь .dll?

    [Reflection.Assembly]::Load('Microsoft.VisualBasic, Version=10.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a').Location;

  • И, в том же ключе, если я знаю имя типа того, что я использую, как узнать, из какой сборки он пришел?

    [Reflection.Assembly]::GetAssembly([Type]).Location

  • Как узнать, какие сборки доступны?

Я предлагаю модуль GAC PowerShell. Get-GacAssembly -Name 'Microsoft.SqlServer.Smo*' | Select Name, Version, FullName работает очень хорошо.

  1. Как я могу увидеть список, который использует Add-Type?

Это немного сложнее. Я не вижу документального списка в Интернете, но я могу описать, как получить к нему доступ с рефлектором .Net.

Сначала выясните, какая библиотека Add-Type исходит из:

Get-Command -Name Add-Type | Select-Object -Property DLL

Откройте полученную DLL с помощью отражателя. Я использовал ILSpy для этого, потому что это FLOSS, но любой рефлектор С# должен работать. Откройте эту библиотеку и посмотрите Microsoft.Powershell.Commands.Utility. В Microsoft.Powershell.Commands должно быть AddTypeCommand. В списке кода для этого есть частный класс, InitializeStrongNameDictionary(). Это список словаря, который сопоставляет короткие имена сильным именам. В библиотеке, на которую я смотрел, почти 750 записей.

Ответ 4

Вот несколько сообщений в блогах с многочисленными примерами способов загрузки сборок в PowerShell v1, v2 и v3.

Пути включают в себя:

  • динамически из исходного файла
  • динамически из сборки
  • с использованием других типов кода, то есть F #

v1.0 Как загрузить сборки .NET на сеансе PowerShell
v2.0 Использование кода CSharp (С#) в скриптах PowerShell 2.0
v3.0 Использование сборок .NET Framework в Windows PowerShell

Ответ 5

Если вы хотите загрузить сборку без ее блокировки в течение сеанса PowerShell, используйте следующую команду:

$bytes = [System.IO.File]::ReadAllBytes($storageAssemblyPath)
[System.Reflection.Assembly]::Load($bytes)

Где $storageAssemblyPath - путь к файлу вашей сборки.

Это особенно полезно, если вам нужно очистить ресурсы в сеансе. Например, в развертывании script.

Ответ 6

Вы можете загрузить всю сборку *.dll с помощью

$Assembly = [System.Reflection.Assembly]::LoadFrom("C:\folder\file.dll");

Ответ 7

[System.Reflection.Assembly]::LoadWithPartialName("Microsoft.SqlServer.Smo") работал у меня.

Ответ 8

Вы можете использовать LoadWithPartialName. Тем не менее, это устарело, как они сказали.

Вы действительно можете согласиться с Add-Type, и в дополнение к другим ответам, если вы не хотите указывать полный путь к файлу .dll, вы можете просто сделать:

Add-Type -AssemblyName "Microsoft.SqlServer.Management.SMO"

Для меня это вернуло ошибку, потому что у меня нет SQL Server (я думаю), однако, с этой же идеей мне удалось загрузить сборку Windows Forms:

Add-Type -AssemblyName "System.Windows.Forms"

Вы можете узнать точное имя сборки, принадлежащее определенному классу на сайте MSDN:

Пример определения имени сборки, принадлежащего определенному классу

Ответ 9

Ни один из ответов не помог мне, поэтому я отправляю решение, которое сработало для меня, все, что мне нужно было сделать, это импортировать модуль SQLPS, я это понял, когда случайно я запустил команду Restore-SqlDatabase и начал работать, что означает, что сборка была упомянута в этом модуле как-то.

Просто запустите:

Import-module SQLPS

Ответ 10

Добавьте ссылки на сборку вверху.

Загрузите необходимые сборки SMO ​​и SmoExtended.

[System.Reflection.Assembly]:: LoadWithPartialName ( "Microsoft.SqlServer.SMO" ) | Из-Null [System.Reflection.Assembly]:: LoadWithPartialName ( "Microsoft.SqlServer.SmoExtended" ) | Из-Null

Ответ 11

Удостоверьтесь, что у вас есть ниже функции, установленные в порядке

1-Microsoft System CLR Типы для SQL Server

2-Общие объекты управления Microsoft SQL Server

3-Microsoft Windows PowerShell Extensions

Также вам может потребоваться загрузить

Add-Type -Path "C:\Program Files\Microsoft SQL Server\110\SDK\Assemblies\Microsoft.SqlServer.Smo.dll"

Add-Type -Path "C:\Program Files\Microsoft SQL Server\110\SDK\Assemblies\Microsoft.SqlServer.SqlWmiManagement.dll"