Le code PowerShell suivant
#Get a server object which corresponds to the default instance
$srv = New-Object -TypeName Microsoft.SqlServer.Management.SMO.Server
... rest of the script ...
Donne le message d'erreur suivant:
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
Chaque réponse sur Internet écrit que je dois charger l'assemblage - bien sûr que je peux lire cela à partir du message d'erreur :-) - la question est:
Comment charger l'assemblage et faire fonctionner le script?
powershell
powershell-3.0
Baxter
la source
la source
This API is now obsolete.
Bien sûr, cela n'empêche pas les gens de l'utiliser.LoadWithPartialName
soit obsolète, les raisons (comme indiqué dans blogs.msdn.com/b/suzcook/archive/2003/05/30/57159.aspx ) ne s'appliquent clairement pas à une session Powershell interactive. Je vous suggère d'ajouter une note indiquant que l'API convient à une utilisation interactive de Powershell.la source
Out-Null
si vous ne voulez pas que le GAC fasse écho.Add-Type -Path [...]; if (!$?) { Add-Type -Path [...] } elseif [...]
.La plupart des gens savent maintenant que
System.Reflection.Assembly.LoadWithPartialName
c'est obsolète, mais il s'avère queAdd-Type -AssemblyName Microsoft.VisualBasic
cela ne se comporte pas beaucoup mieux queLoadWithPartialName
:Qu'est - ce que Microsoft dit que vous êtes réellement censé faire quelque chose comme ceci:
Ou, si vous connaissez le chemin, quelque chose comme ceci:
Ce nom long donné pour l'assembly est connu sous le nom de nom fort , qui est à la fois unique à la version et à l'assembly, et est également parfois appelé nom complet.
Mais cela laisse quelques questions sans réponse:
Comment déterminer le nom fort de ce qui est réellement chargé sur mon système avec un nom partiel donné?
[System.Reflection.Assembly]::LoadWithPartialName($TypeName).Location;
[System.Reflection.Assembly]::LoadWithPartialName($TypeName).FullName;
Ceux-ci devraient également fonctionner:
Si je veux que mon script utilise toujours une version spécifique d'un .dll mais que je ne peux pas être certain de l'endroit où il est installé, comment déterminer quel est le nom fort du .dll?
[System.Reflection.AssemblyName]::GetAssemblyName($Path).FullName;
Ou:
Si je connais le nom fort, comment puis-je déterminer le chemin .dll?
[Reflection.Assembly]::Load('Microsoft.VisualBasic, Version=10.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a').Location;
Et, dans le même ordre d'idées, si je connais le nom de type de ce que j'utilise, comment savoir de quel assemblage il provient?
[Reflection.Assembly]::GetAssembly([Type]).Location
[Reflection.Assembly]::GetAssembly([Type]).FullName
Comment voir quels assemblages sont disponibles?
Je suggère le module GAC PowerShell .
Get-GacAssembly -Name 'Microsoft.SqlServer.Smo*' | Select Name, Version, FullName
fonctionne plutôt bien.Add-Type
utilise?C'est un peu plus complexe. Je peux décrire comment y accéder pour n'importe quelle version de PowerShell avec un réflecteur .Net (voir la mise à jour ci-dessous pour PowerShell Core 6.0).
Tout d'abord, déterminez de quelle bibliothèque
Add-Type
provient:Ouvrez la DLL résultante avec votre réflecteur. J'ai utilisé ILSpy pour cela parce que c'est FLOSS, mais n'importe quel réflecteur C # devrait fonctionner. Ouvrez cette bibliothèque et regardez dedans
Microsoft.Powershell.Commands.Utility
. En dessousMicrosoft.Powershell.Commands
, il devrait y en avoirAddTypeCommand
.Dans le code inscripteur pour cela, il y a une classe privée,
InitializeStrongNameDictionary()
. Cela répertorie le dictionnaire qui mappe les noms courts aux noms forts. J'ai regardé près de 750 entrées dans la bibliothèque.Mise à jour: maintenant que PowerShell Core 6.0 est open source. Pour cette version, vous pouvez ignorer les étapes ci-dessus et voir le code directement en ligne dans leur référentiel GitHub . Cependant, je ne peux pas garantir que ce code correspond à une autre version de PowerShell.
la source
Add-Type
ouLoadWithPartialName()
, mais vous devez être conscient que la première ne sera pas cohérente à 100% entre les versions et la seconde est une méthode obsolète. En d'autres termes, .Net veut que vous vous souciez de la version de la bibliothèque que vous chargez.Add-Type -Path
, qui est le deuxième code mentionné, ouAssembly.LoadFrom()
qui résout les dépendances pour vous (et, pour autant que je sache, est ce quiAdd-Type -Path
utilise). Le seul moment où vous devriez utiliserAssembly.LoadFile()
est si vous devez charger plusieurs assemblys qui ont la même identité mais des chemins différents. C'est une situation étrange.Si vous souhaitez charger un assembly sans le verrouiller pendant la durée de la session PowerShell , utilisez ceci:
Où
$storageAssemblyPath
est le chemin de fichier de votre assembly.Ceci est particulièrement utile si vous avez besoin de nettoyer les ressources de votre session. Par exemple dans un script de déploiement.
la source
Voici quelques articles de blog avec de nombreux exemples de façons de charger des assemblys dans PowerShell v1, v2 et v3.
Les moyens comprennent:
v1.0 Comment charger des assemblys .NET dans une session PowerShell
v2.0 à l' aide de code CSharp (C #) dans des scripts PowerShell 2.0
v3.0 à l' aide d' assemblys .NET Framework dans Windows PowerShell
la source
Vous pouvez charger l'ensemble de l'assembly * .dll avec
la source
Aucune des réponses ne m'a aidé, donc je poste la solution qui a fonctionné pour moi, tout ce que j'avais à faire est d'importer le module SQLPS, je m'en suis rendu compte lorsque par accident j'ai exécuté la commande Restore-SqlDatabase et j'ai commencé à travailler, ce qui signifie que l'assemblage a été référencé dans ce module d'une manière ou d'une autre.
Exécutez simplement:
Remarque: merci Jason d'avoir noté que SQLPS est obsolète
à la place, exécutez:
ou
la source
sqlps
est obsolète en faveur du modulesqlserver
[System.Reflection.Assembly]::LoadWithPartialName("Microsoft.SqlServer.Smo")
travaillé pour moi.la source
Vous pourriez utiliser
LoadWithPartialName
. Cependant, cela est obsolète comme ils l'ont dit.Vous pouvez en effet accepter
Add-Type
, et en plus des autres réponses, si vous ne souhaitez pas spécifier le chemin complet du fichier .dll, vous pouvez simplement faire:Pour moi, cela a renvoyé une erreur, car SQL Server n'est pas installé (je suppose), cependant, avec cette même idée, j'ai pu charger l'assembly Windows Forms:
Vous pouvez trouver le nom d'assembly précis appartenant à la classe particulière sur le site MSDN:
la source
Assurez-vous que les fonctionnalités ci-dessous sont installées dans l'ordre
Vous devrez peut-être également charger
la source
Ajoutez les références d'assemblage en haut.
la source