Следующий код 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
Каждый ответ в Интернете пишет, что я должен загрузить сборку - конечно, я могу прочитать это из сообщения об ошибке :-) - вопрос такой:
Как загрузить сборку и заставить скрипт работать?
powershell
powershell-3.0
Baxter
источник
источник
This API is now obsolete.
Конечно, это не мешает людям использовать его.LoadWithPartialName
это устарело, причины (как изложено в blogs.msdn.com/b/suzcook/archive/2003/05/30/57159.aspx ) явно не применимы для интерактивного сеанса Powershell. Я предлагаю вам добавить примечание, что API подходит для интерактивного использования Powershell.источник
Out-Null
если не хотите, чтобы GAC отображал что-либо.Add-Type -Path [...]; if (!$?) { Add-Type -Path [...] } elseif [...]
.Большинство людей к настоящему моменту знают, что
System.Reflection.Assembly.LoadWithPartialName
это устарело, но оказывается, чтоAdd-Type -AssemblyName Microsoft.VisualBasic
не ведет себя намного лучше, чемLoadWithPartialName
:Microsoft говорит, что на самом деле вы должны делать что-то вроде этого:
Или, если вы знаете путь, что-то вроде этого:
Это длинное имя, данное для сборки, называется строгим именем , которое уникально как для версии, так и для сборки, а также иногда называется полным именем.
Но это оставляет пару вопросов без ответа:
Как определить строгое имя того, что на самом деле загружается в моей системе с данным частичным именем?
[System.Reflection.Assembly]::LoadWithPartialName($TypeName).Location;
[System.Reflection.Assembly]::LoadWithPartialName($TypeName).FullName;
Они также должны работать:
Если я хочу, чтобы в моем сценарии всегда использовалась определенная версия .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
[Reflection.Assembly]::GetAssembly([Type]).FullName
Как посмотреть какие сборки доступны?
Я предлагаю модуль GAC PowerShell .
Get-GacAssembly -Name 'Microsoft.SqlServer.Smo*' | Select Name, Version, FullName
работает довольно хорошоAdd-Type
использует?Это немного сложнее. Я могу описать, как получить к нему доступ для любой версии PowerShell с помощью отражателя .Net (см. Обновление ниже для PowerShell Core 6.0).
Сначала выясните, из какой библиотеки
Add-Type
происходит:Откройте полученную DLL вашим отражателем. Я использовал ILSpy для этого, потому что это FLOSS, но любой отражатель C # должен работать. Откройте эту библиотеку и посмотрите
Microsoft.Powershell.Commands.Utility
. ПодMicrosoft.Powershell.Commands
, там должно бытьAddTypeCommand
.В листинге кода для этого есть закрытый класс
InitializeStrongNameDictionary()
. Это перечисляет словарь, который отображает короткие имена в строгие имена. В библиотеке я посмотрел почти 750 записей.Обновление: теперь, когда PowerShell Core 6.0 с открытым исходным кодом. Для этой версии вы можете пропустить описанные выше шаги и увидеть код прямо онлайн в их репозитории GitHub . Однако я не могу гарантировать, что этот код соответствует любой другой версии PowerShell.
источник
Add-Type
илиLoadWithPartialName()
, но вы должны знать, что первое не будет на 100% согласованным в разных версиях, а второе - устаревший метод. Другими словами, .Net хочет, чтобы вы заботились о версии загружаемой вами библиотеки.Add-Type -Path
, который является вторым упомянутым кодом илиAssembly.LoadFrom()
который разрешает зависимости для вас (и, насколько я могу судить, это то, чтоAdd-Type -Path
использует). Единственное время, которое вам следует использовать,Assembly.LoadFile()
- это если вам нужно загрузить несколько сборок, которые имеют одинаковые идентификационные данные, но разные пути. Это странная ситуация.Если вы хотите загрузить сборку без блокировки во время сеанса PowerShell , используйте это:
Где
$storageAssemblyPath
находится путь к файлу вашей сборки.Это особенно полезно, если вам нужно очистить ресурсы в течение вашего сеанса. Например, в сценарии развертывания.
источник
Вот некоторые сообщения в блоге с многочисленными примерами способов загрузки сборок в PowerShell v1, v2 и v3.
Способы включают в себя:
v1.0 Как загрузить сборки .NET в сеансе PowerShell
v2.0 Использование кода CSharp (C #) в сценариях PowerShell 2.0
v3.0 Использование сборок .NET Framework в Windows PowerShell
источник
Вы можете загрузить всю сборку * .dll с помощью
источник
Ни один из ответов не помог мне, поэтому я публикую решение, которое сработало для меня, все, что мне нужно было сделать, это импортировать модуль SQLPS. Я понял это, когда случайно запустил команду Restore-SqlDatabase и начал работать, то есть сборка упоминалась в этом модуле как-то.
Просто беги:
Примечание: спасибо Джейсону за то, что он отметил, что SQLPS устарел
вместо этого запустите:
или
источник
sqlps
является устаревшим в пользу модуляsqlserver
[System.Reflection.Assembly]::LoadWithPartialName("Microsoft.SqlServer.Smo")
работал на меня.источник
Вы могли бы использовать
LoadWithPartialName
. Тем не менее, это устарело, как они сказали.Вы действительно можете согласиться
Add-Type
, и в дополнение к другим ответам, если вы не хотите указывать полный путь к файлу .dll, вы можете просто сделать:Для меня это вернуло ошибку, потому что у меня не установлен SQL Server (я думаю), однако, с этой же идеей я смог загрузить сборку Windows Forms:
Точное имя сборки, принадлежащее определенному классу, можно узнать на сайте MSDN:
источник
Убедитесь, что нижеуказанные функции установлены в порядке
Также вам может понадобиться загрузить
источник
Добавьте ссылки на сборки вверху.
источник