如何加载组件在PowerShell中?(How to load assemblies in Powe

2019-06-18 12:53发布

下面的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

互联网上的每台答案写道,我必须加载组件 - 好相信我可以阅读从错误信息:-) - 问题是:

你如何加载程序集,使脚本工作?

Answer 1:

LoadWithPartialName已被弃用。 对PowerShell的V3推荐的解决方案是使用Add-Type cmdlet的如:

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

有多种不同的版本,你可能想选择一个特定版本。 :-)



Answer 2:

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


Answer 3:

大多数人现在都知道System.Reflection.Assembly.LoadWithPartialName已被弃用,但事实证明, Add-Type -AssemblyName Microsoft.VisualBasic 不表现大大优于LoadWithPartialName

而不是让任何试图分析在你的系统的背景下您的要求,[添加型]着眼于静态的,内部表的“局部名”翻译为“全名”。

如果你的“部分名称”并没有在他们的表上,你的脚本将失败。

如果您的计算机上安装该组件的多个版本,有没有智能算法在它们之间进行选择。 你会得到哪一个出现在他们的桌子,可能是年纪大了,已经过时的。

如果您已经安装的版本都比过时的一个表中的更新,你的脚本将失败。

添加型拥有像“部分名称”没有智能分析器.LoadWithPartialNames

什么微软说你其实应该做的是这样的:

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'

对于装配鉴于长的名字被称为强名称 ,这既是独特的版本和程序集,并且有时也被称为全名。

但是,这留下了几个悬而未决的问题:

  1. 我如何确定什么实际加载在我的系统给定的部分名称的强名称?

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

  2. 如果我想我的脚本始终使用一个.dll的特定版本,但我不能肯定它是安装在哪里,我怎么确定强名称是从该.dll是什么?

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

  3. 如果我知道强名称,我怎么决定该.dll的路径?

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

  4. 而且,在此类似,如果我知道我使用的是什么类型的名字,我怎么知道什么是汇编它是从哪里来的?

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

  5. 如何看什么组件有哪些?

我建议GAC PowerShell的模块 。 Get-GacAssembly -Name 'Microsoft.SqlServer.Smo*' | Select Name, Version, FullName Get-GacAssembly -Name 'Microsoft.SqlServer.Smo*' | Select Name, Version, FullName工作得很好。

  1. 我怎样才能看到列表中Add-Type使用?

这是一个比较复杂。 我可以描述如何访问它的PowerShell的任何版本与.NET反射器(参见下面的PowerShell核心6.0更新)。

首先,找出哪些库Add-Type来自:

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

打开你的反射所产生的DLL。 我用ILSpy对于这一点,因为它的FLOSS,但任何C#反射应该工作。 打开库,并查看Microsoft.Powershell.Commands.Utility 。 在Microsoft.Powershell.Commands ,应该有AddTypeCommand

在该代码列表中,有一个私有类, InitializeStrongNameDictionary() 列出映射短名称的强名称的字典。 有一个在我看过的图书馆几乎750项。

更新:现在PowerShell核心6.0是开源的。 对于该版本,你可以跳过上述步骤,看到了代码直接在网上他们的GitHub仓库 。 我不能保证这些代码的PowerShell的任何其他版本相匹配,但是。



Answer 4:

如果要加载程序集,而不PowerShell会话的持续时间内将其锁定 ,使用此:

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

其中$storageAssemblyPath是您的程序集的文件路径。

如果你需要清理ressources您的会话中,这是特别有用的。 例如,在部署脚本。



Answer 5:

下面是用方法来加载在PowerShell中V1,V2和V3组件的例子不胜枚举一些博客文章。

该方法包括:

  • 动态地从一个源文件
  • 动态地从一个组件
  • 使用其他代码类型,即F#

1.0 如何加载.NET程序集在一个PowerShell会话
2.0 在Powershell脚本2.0使用CSHARP(C#)代码
3.0 在Windows PowerShell中使用.NET Framework组件



Answer 6:

你可以加载整个的* .dll组件,

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


Answer 7:

答案都不帮我,所以我张贴为我工作的解决方案,所有我需要做的是导入SQLPS模块,我意识到这一点时不小心我跑的恢复,SqlDatabase命令并开始工作,这意味着装配该模块中被引用的莫名其妙。

赶紧跑:

Import-module SQLPS

注:由于贾森指出,SQLPS已被弃用

去运行:

Import-Module SqlServer

要么

Install-Module SqlServer


Answer 8:

[System.Reflection.Assembly]::LoadWithPartialName("Microsoft.SqlServer.Smo")为我工作。



Answer 9:

你可以使用LoadWithPartialName 。 然而,当他们说,已经过时了。

你可以用确实一起去Add-Type ,并且除了其他的答案,如果你不想指定.dll文件的完整路径,你可以只是简单地做:

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

对我来说这将返回一个错误,因为我没有安装SQL Server的(我猜),然而,与此相同的想法,我能够加载Windows窗体组件:

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

你可以找到属于在MSDN网站上的特定类的精确装配名称:



Answer 10:

在顶部添加组件引用。

加载所需的组件SMO和SmoExtended。

[System.Reflection.Assembly] :: LoadWithPartialName( “Microsoft.SqlServer.SMO”)| 外空[System.Reflection.Assembly] :: LoadWithPartialName( “Microsoft.SqlServer.SmoExtended”)| 外空



Answer 11:

请确保您有以下功能安装,以

1 - 微软系统CLR类型的SQL Server

2,Microsoft SQL Server的共享管理对象

3,微软的Windows PowerShell扩展

您可能还需要加载

添加型-Path “C:\ Program Files文件\ Microsoft SQL Server的\ 110 \ SDK \组件\ Microsoft.SqlServer.Smo.dll”

添加型-Path “C:\ Program Files文件\ Microsoft SQL Server的\ 110 \ SDK \组件\ Microsoft.SqlServer.SqlWmiManagement.dll”



文章来源: How to load assemblies in PowerShell?