powershell - comando - .bat mensaje emergente
Cómo cargar ensamblajes en PowerShell? (11)
Aquí hay algunas publicaciones en el blog con numerosos ejemplos de formas de cargar ensamblajes en PowerShell v1, v2 y v3.
Las formas incluyen:
- dinámicamente desde un archivo fuente
- dinámicamente desde un ensamblado
- usando otros tipos de código, es decir, F #
v1.0 Cómo cargar ensamblajes .NET en una sesión de PowerShell
v2.0 Uso del código CSharp (C #) en los scripts de PowerShell 2.0
v3.0 Uso de ensamblados de .NET Framework en Windows PowerShell
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 ensamblado, y estoy seguro de que puedo leerlo desde el mensaje de error :-) - la pregunta es:
¿Cómo carga el ensamblaje y hace que el script funcione?
Asegúrate de tener las siguientes funciones instaladas en orden
1-Microsoft System CLR Types para SQL Server
Objetos de administración compartida de 2-Microsoft SQL Server
Extensiones de 3-Microsoft Windows PowerShell
También es posible que tengas que cargar
Add-Type -Path "C: / Archivos de programa / Microsoft SQL Server / 110 / SDK / Assemblies / Microsoft.SqlServer.Smo.dll"
Add-Type -Path "C: / Archivos de programa / Microsoft SQL Server / 110 / SDK / Assemblies / Microsoft.SqlServer.SqlWmiManagement.dll"
La mayoría de la gente sabe ahora que System.Reflection.Assembly.LoadWithPartialName
está en desuso, pero resulta que Add-Type -AssemblyName Microsoft.VisualBasic
no se comporta mucho mejor que LoadWithPartialName
:
En lugar de intentar analizar su solicitud en el contexto de su sistema, [Agregar-Tipo] mira una tabla interna estática para traducir el "nombre parcial" a un "nombre completo".
Si su "nombre parcial" no aparece en su tabla, su script fallará.
Si tiene múltiples versiones del ensamblaje instaladas en su computadora, no existe un algoritmo inteligente para elegir entre ellas. Obtendrá el que aparezca en su mesa, probablemente el más antiguo y anticuado.
Si las versiones que ha instalado son todas más nuevas que la obsoleta de la tabla, su secuencia de comandos fallará.
Add-Type no tiene un analizador inteligente de "nombres parciales" como
.LoadWithPartialNames
.
Lo que Microsoft dice que se supone que debes hacer es algo como esto:
Add-Type -AssemblyName ''Microsoft.VisualBasic, Version=10.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a''
O, si conoce el camino, algo como esto:
Add-Type -Path ''C:/WINDOWS/Microsoft.Net/assembly/GAC_MSIL/Microsoft.VisualBasic/v4.0_10.0.0.0__b03f5f7f11d50a3a/Microsoft.VisualBasic.dll''
Ese nombre largo dado para el ensamblado se conoce como el nombre fuerte , que es único para la versión y el conjunto, y también se conoce como el nombre completo.
Pero esto deja un par de preguntas sin respuesta:
¿Cómo determino el nombre fuerte de lo que se está cargando realmente en mi sistema con un nombre parcial dado?
[System.Reflection.Assembly]::LoadWithPartialName($TypeName).Location;
[System.Reflection.Assembly]::LoadWithPartialName($TypeName).FullName;
Si quiero que mi script siempre use una versión específica de .dll pero no puedo estar seguro de dónde está instalado, ¿cómo puedo determinar cuál es el nombre fuerte de .dll?
[System.Reflection.AssemblyName]::GetAssemblyName($Path).FullName;
Si conozco el nombre fuerte, ¿cómo determino el camino .dll?
[Reflection.Assembly]::Load(''Microsoft.VisualBasic, Version=10.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a'').Location;
Y, en una línea similar, si conozco el nombre de tipo de lo que estoy usando, ¿cómo sé de qué ensamblaje proviene?
[Reflection.Assembly]::GetAssembly([Type]).Location
[Reflection.Assembly]::GetAssembly([Type]).FullName
¿Cómo veo qué ensamblajes están disponibles?
Sugiero el módulo GAC PowerShell . Get-GacAssembly -Name ''Microsoft.SqlServer.Smo*'' | Select Name, Version, FullName
Get-GacAssembly -Name ''Microsoft.SqlServer.Smo*'' | Select Name, Version, FullName
funciona bastante bien.
- ¿Cómo puedo ver la lista que usa
Add-Type
?
Esto es un poco más complejo. No veo ninguna lista documentada en línea, pero puedo describir cómo acceder a ella con un reflector .Net.
En primer lugar, averigüe de qué biblioteca viene Add-Type
:
Get-Command -Name Add-Type | Select-Object -Property DLL
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 busque en Microsoft.Powershell.Commands.Utility
. En Microsoft.Powershell.Commands
, debe haber AddTypeCommand
. En la lista de códigos 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.
Ninguna de las respuestas me ayudó, así que estoy publicando la solución que funcionó para mí, todo lo que tuve que hacer es 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 el conjunto fue referenciado en ese módulo de alguna manera.
Solo corre:
Import-module SQLPS
Puede cargar el conjunto completo * .dll con
$Assembly = [System.Reflection.Assembly]::LoadFrom("C:/folder/file.dll");
Puede usar LoadWithPartialName
. Sin embargo, eso está en desuso ya que dijeron.
De hecho, puede seguir con Add-Type
, y además de las otras respuestas, si no desea especificar la ruta completa del archivo .dll, simplemente puede hacer:
Add-Type -AssemblyName "Microsoft.SqlServer.Management.SMO"
Para mí esto devolvió un error, porque no tengo SQL Server instalado (supongo), sin embargo, con esta misma idea, pude cargar el ensamblado de Windows Forms:
Add-Type -AssemblyName "System.Windows.Forms"
Puede encontrar el nombre de ensamblado preciso que pertenece a la clase particular en el sitio de MSDN:
Si desea cargar un ensamblaje sin bloquearlo durante la sesión de PowerShell , use esto:
$bytes = [System.IO.File]::ReadAllBytes($storageAssemblyPath)
[System.Reflection.Assembly]::Load($bytes)
Donde $storageAssemblyPath
es la $storageAssemblyPath
archivo de su ensamblaje.
Esto es especialmente útil si necesita limpiar los recursos dentro de su sesión. Por ejemplo, en un script de despliegue.
LoadWithPartialName
ha quedado en desuso. La solución recomendada para PowerShell V3 es usar el cmdlet Add-Type
por ejemplo:
Add-Type -Path ''C:/Program Files/Microsoft SQL Server/110/SDK/Assemblies/Microsoft.SqlServer.Smo.dll''
Existen múltiples versiones diferentes y es posible que desee elegir una versión en particular. :-)
[System.Reflection.Assembly]::LoadWithPartialName("Microsoft.SqlServer.Smo")
funcionó para mí.
Agregue las referencias de ensamblaje en la parte superior.
Cargue los ensamblados necesarios SMO y SmoExtended.
[System.Reflection.Assembly] :: LoadWithPartialName ("Microsoft.SqlServer.SMO") | Out-Null [System.Reflection.Assembly] :: LoadWithPartialName ("Microsoft.SqlServer.SmoExtended") | Out-Null
[System.Reflection.Assembly]::LoadWithPartialName("Microsoft.SqlServer.Smo")