El siguiente código de PowerShell
#Get a server object which corresponds to the default instance
$srv = New-Object -TypeName Microsoft.SqlServer.Management.SMO.Server
... rest of the script ...
Da el siguiente mensaje de error:
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
Cada respuesta en Internet escribe que tengo que cargar el ensamblaje, seguro que puedo leerlo en el mensaje de error :-), la pregunta es:
¿Cómo carga el ensamblaje y hace que el script funcione?
powershell
powershell-3.0
Baxter
fuente
fuente
This API is now obsolete.
Por supuesto, eso no impide que la gente lo use.LoadWithPartialName
ha quedado en desuso, las razones (como se describe en blogs.msdn.com/b/suzcook/archive/2003/05/30/57159.aspx ) claramente no se aplican a una sesión interactiva de Powershell. Le sugiero que agregue una nota de que la API está bien para el uso interactivo de Powershell.fuente
Out-Null
si no desea que el GAC haga eco de cosas.Add-Type -Path [...]; if (!$?) { Add-Type -Path [...] } elseif [...]
.La mayoría de las personas ya saben que
System.Reflection.Assembly.LoadWithPartialName
está en desuso, pero resulta queAdd-Type -AssemblyName Microsoft.VisualBasic
no se comporta mucho mejor queLoadWithPartialName
:Lo que Microsoft dice que está en realidad supone que debe hacer es algo como esto:
O, si conoce el camino, algo como esto:
Ese nombre largo dado para el ensamblado se conoce como el nombre seguro , que es exclusivo de la versión y el ensamblado, y también a veces se conoce como el nombre completo.
Pero esto deja un par de preguntas sin respuesta:
¿Cómo determino el nombre seguro de lo que realmente se está cargando en mi sistema con un nombre parcial dado?
[System.Reflection.Assembly]::LoadWithPartialName($TypeName).Location;
[System.Reflection.Assembly]::LoadWithPartialName($TypeName).FullName;
Estos también deberían funcionar:
Si quiero que mi script siempre use una versión específica de un .dll pero no puedo estar seguro de dónde está instalado, ¿cómo puedo determinar cuál es el nombre seguro del .dll?
[System.Reflection.AssemblyName]::GetAssemblyName($Path).FullName;
O:
Si conozco el nombre seguro, ¿cómo determino la ruta .dll?
[Reflection.Assembly]::Load('Microsoft.VisualBasic, Version=10.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a').Location;
Y, en una línea similar, si sé el nombre del tipo de lo que estoy usando, ¿cómo sé de qué conjunto proviene?
[Reflection.Assembly]::GetAssembly([Type]).Location
[Reflection.Assembly]::GetAssembly([Type]).FullName
¿Cómo veo qué conjuntos están disponibles?
Sugiero el módulo GAC PowerShell .
Get-GacAssembly -Name 'Microsoft.SqlServer.Smo*' | Select Name, Version, FullName
funciona bastante bienAdd-Type
usa?Esto es un poco más complejo. Puedo describir cómo acceder a él para cualquier versión de PowerShell con un reflector .Net (consulte la actualización a continuación para PowerShell Core 6.0).
Primero, descubra de qué biblioteca
Add-Type
proviene:Abra la DLL resultante con su reflector. He usado ILSpy para esto porque es FLOSS, pero cualquier reflector C # debería funcionar. Abra esa biblioteca y mire adentro
Microsoft.Powershell.Commands.Utility
. DebajoMicrosoft.Powershell.Commands
, debería haberAddTypeCommand
.En el listado de código para eso, hay una clase privada,
InitializeStrongNameDictionary()
. Eso enumera el diccionario que asigna los nombres cortos a los nombres fuertes. Hay casi 750 entradas en la biblioteca que he visto.Actualización: ahora que PowerShell Core 6.0 es de código abierto. Para esa versión, puede omitir los pasos anteriores y ver el código directamente en línea en su repositorio de GitHub . Sin embargo, no puedo garantizar que ese código coincida con cualquier otra versión de PowerShell.
fuente
Add-Type
oLoadWithPartialName()
, pero debes tener en cuenta que el primero no será 100% consistente en todas las versiones y el último es un método obsoleto. En otras palabras, .Net quiere que le importe la versión de la biblioteca que carga.Add-Type -Path
, que es el segundo código mencionado oAssembly.LoadFrom()
que resuelve las dependencias para usted (y, hasta donde puedo decir, es lo queAdd-Type -Path
usa). El único momento que debería usarAssembly.LoadFile()
es si necesita cargar varios ensamblajes que tienen la misma identidad pero diferentes rutas. Esa es una situación extraña.Si desea cargar un ensamblaje sin bloquearlo durante la sesión de PowerShell , use esto:
¿Dónde
$storageAssemblyPath
está la ruta de archivo de su ensamblado?Esto es especialmente útil si necesita limpiar los recursos dentro de su sesión. Por ejemplo en un script de implementación.
fuente
Aquí hay algunas publicaciones de blog con numerosos ejemplos de formas de cargar ensamblados en PowerShell v1, v2 y v3.
Las formas incluyen:
v1.0 Cómo cargar ensamblados .NET en una sesión de PowerShell
v2.0 usando el código CSharp (C #) en los scripts de PowerShell 2.0
v3.0 Usando ensamblados de .NET Framework en Windows PowerShell
fuente
Puede cargar todo el conjunto * .dll con
fuente
Ninguna de las respuestas me ayudó, así que estoy publicando la solución que funcionó para mí, todo lo que tuve que hacer fue importar el módulo SQLPS, me di cuenta de esto cuando accidentalmente ejecuté el comando Restore-SqlDatabase y comencé a trabajar, lo que significa que la asamblea fue referenciada en ese módulo de alguna manera.
Solo corre:
Nota: Gracias Jason por notar que SQLPS está en desuso
en lugar de ejecutar:
o
fuente
sqlps
está en desuso a favor del módulosqlserver
[System.Reflection.Assembly]::LoadWithPartialName("Microsoft.SqlServer.Smo")
trabajó para mi.fuente
Podrías usar
LoadWithPartialName
. Sin embargo, eso está en desuso como dijeron.De hecho, puede aceptar
Add-Type
, y además de las otras respuestas, si no desea especificar la ruta completa del archivo .dll, simplemente puede hacer:Para mí, esto devolvió un error, porque no tengo instalado SQL Server (supongo), sin embargo, con esta misma idea pude cargar el ensamblado de formularios Windows Forms:
Puede encontrar el nombre de ensamblado preciso que pertenece a la clase particular en el sitio de MSDN:
fuente
Asegúrese de tener las siguientes funciones instaladas en orden
También es posible que deba cargar
fuente
Agregue las referencias de ensamblaje en la parte superior.
fuente