O seguinte código do PowerShell
#Get a server object which corresponds to the default instance
$srv = New-Object -TypeName Microsoft.SqlServer.Management.SMO.Server
... rest of the script ...
Dá a seguinte mensagem de erro:
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
Todas as respostas na Internet escrevem que eu tenho que carregar o assembly - com certeza eu posso ler isso na mensagem de erro :-) - a pergunta é:
Como você carrega a montagem e faz o script funcionar?
powershell
powershell-3.0
Baxter
fonte
fonte
This API is now obsolete.
Obviamente, isso não impede as pessoas de usá-lo.LoadWithPartialName
tenha sido descontinuado, os motivos (conforme descrito em blogs.msdn.com/b/suzcook/archive/2003/05/30/57159.aspx ) claramente não se aplicam a uma sessão interativa do Powershell. Sugiro que você adicione uma nota de que a API é adequada para o uso interativo do Powershell.fonte
Out-Null
se não quiser que o GAC faça eco.Add-Type -Path [...]; if (!$?) { Add-Type -Path [...] } elseif [...]
.A maioria das pessoas sabe até agora que
System.Reflection.Assembly.LoadWithPartialName
está obsoleta, mas acontece queAdd-Type -AssemblyName Microsoft.VisualBasic
não se comporta muito melhor do queLoadWithPartialName
:O que a Microsoft diz que você realmente deve fazer é algo como isto:
Ou, se você conhece o caminho, algo como isto:
Esse nome longo dado para a montagem é conhecido como nome forte , que é exclusivo da versão e do assembly, e também é conhecido como nome completo.
Mas isso deixa algumas perguntas sem resposta:
Como determino o nome forte do que realmente está sendo carregado no meu sistema com um nome parcial fornecido?
[System.Reflection.Assembly]::LoadWithPartialName($TypeName).Location;
[System.Reflection.Assembly]::LoadWithPartialName($TypeName).FullName;
Estes também devem funcionar:
Se quiser que meu script sempre use uma versão específica de uma .dll, mas não tenha certeza de onde está instalado, como determino qual é o nome forte da .dll?
[System.Reflection.AssemblyName]::GetAssemblyName($Path).FullName;
Ou:
Se eu souber o nome forte, como determino o caminho .dll?
[Reflection.Assembly]::Load('Microsoft.VisualBasic, Version=10.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a').Location;
E, de maneira semelhante, se eu sei o nome do tipo do que estou usando, como sei de que montagem ele está vindo?
[Reflection.Assembly]::GetAssembly([Type]).Location
[Reflection.Assembly]::GetAssembly([Type]).FullName
Como vejo quais montagens estão disponíveis?
Sugiro o módulo GAC PowerShell .
Get-GacAssembly -Name 'Microsoft.SqlServer.Smo*' | Select Name, Version, FullName
funciona muito bem.Add-Type
usa?Isso é um pouco mais complexo. Posso descrever como acessá-lo para qualquer versão do PowerShell com um refletor .Net (consulte a atualização abaixo para o PowerShell Core 6.0).
Primeiro, descubra de que biblioteca
Add-Type
vem:Abra a DLL resultante com seu refletor. Eu usei o ILSpy para isso porque é FLOSS, mas qualquer refletor em C # deve funcionar. Abra essa biblioteca e veja
Microsoft.Powershell.Commands.Utility
. AbaixoMicrosoft.Powershell.Commands
, deve haverAddTypeCommand
.Na lista de códigos para isso, há uma classe privada
InitializeStrongNameDictionary()
,. Isso lista o dicionário que mapeia os nomes abreviados para os nomes fortes. Há quase 750 entradas na biblioteca que eu olhei.Atualização: Agora que o PowerShell Core 6.0 é de código aberto. Para essa versão, você pode pular as etapas acima e ver o código diretamente online no repositório do GitHub . Não posso garantir que esse código corresponda a qualquer outra versão do PowerShell, no entanto.
fonte
Add-Type
orLoadWithPartialName()
, mas precisa estar ciente de que o primeiro não será 100% consistente entre as versões e o último é um método obsoleto. Em outras palavras, o .Net deseja que você se preocupe com a versão da biblioteca que você carrega.Add-Type -Path
, que é o segundo código mencionado ouAssembly.LoadFrom()
que resolve dependências para você (e, até onde eu sei, é o queAdd-Type -Path
usa). O único momento que você deve usarAssembly.LoadFile()
é se você precisa carregar vários assemblies que têm a mesma identidade, mas caminhos diferentes. Essa é uma situação estranha.Se você deseja carregar uma montagem sem travá-la durante a sessão do PowerShell , use o seguinte:
Onde
$storageAssemblyPath
está o caminho do arquivo da sua montagem.Isso é especialmente útil se você precisar limpar os recursos da sua sessão. Por exemplo, em um script de implantação.
fonte
Aqui estão algumas postagens de blog com vários exemplos de maneiras de carregar montagens no PowerShell v1, v2 e v3.
As maneiras incluem:
v1.0 Como carregar assemblies .NET em uma sessão do PowerShell
v2.0 usando o código CSharp (C #) nos scripts do PowerShell 2.0
v3.0 usando assemblies do .NET Framework no Windows PowerShell
fonte
Você pode carregar o assembly * .dll inteiro com
fonte
Nenhuma das respostas me ajudou, então, eu estou postando a solução que funcionou para mim. Tudo o que eu precisava fazer era importar o módulo SQLPS. Percebi isso quando, por acidente, executei o comando Restore-SqlDatabase e comecei a trabalhar, o que significa que a montagem foi referenciada nesse módulo de alguma forma.
Apenas corra:
Nota: Obrigado Jason por observar que o SQLPS está obsoleto
em vez disso, execute:
ou
fonte
sqlps
é depreciado em favor do módulosqlserver
[System.Reflection.Assembly]::LoadWithPartialName("Microsoft.SqlServer.Smo")
trabalhou para mim.fonte
Você poderia usar
LoadWithPartialName
. No entanto, isso foi preterido como eles disseram.Você pode acompanhar
Add-Type
e, além das outras respostas, se não desejar especificar o caminho completo do arquivo .dll, basta:Para mim, isso retornou um erro, porque eu não tenho o SQL Server instalado (eu acho), no entanto, com essa mesma ideia, consegui carregar o assembly do Windows Forms:
Você pode descobrir o nome exato do assembly pertencente à classe específica no site MSDN:
fonte
Verifique se os recursos abaixo estão instalados em ordem
Também pode ser necessário carregar
fonte
Adicione as referências de montagem na parte superior.
fonte