Import-Module -Assembly error - powershell

I am trying to write PowerShell and am failing miserably.
Set-ExecutionPolicy Unrestricted
Import-Module -Assembly PowerShellXrm.Framework.CI.PowerShell.dll
and
Set-ExecutionPolicy Unrestricted
Import-Module -Assembly "PowerShellXrm.Framework.CI.PowerShell.dll"
and get the following error.
Import-Module : Cannot bind parameter 'Assembly'. Cannot convert the
"PowerShellXrm.Framework.CI.PowerShell.dll" value of type "System.String"
to type "System.Reflection.Assembly".
At line:1 char:25
+ Import-Module -Assembly PowerShellXrm.Framework.CI.PowerShell.dll
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : InvalidArgument: (:) [Import-Module], ParameterBindingException
+ FullyQualifiedErrorId : CannotConvertArgumentNoMessage,Microsoft.PowerShell.Commands.ImportModuleCommand
The PowerShell script is saved in the same location as the PowerShellXrm.Framework.CI.PowerShell.dll assembly. I have also tried including the full path to the assembly with no luck.

If you want to import a PowerShell module from a DLL file simply pass the filename:
Import-Module 'PowerShellXrm.Framework.CI.PowerShell.dll'
Use the full path if the file is not located in one of the folders listed in $env:PSModulePath:
Import-Module 'C:\path\to\PowerShellXrm.Framework.CI.PowerShell.dll'
As documented the -Assembly parameter is for importing assembly objects, not assembly files.
-Assembly<Assembly[]>
Imports the cmdlets and providers implemented in the specified assembly objects. Enter a variable that contains assembly objects or a command that creates assembly objects. You can also pipe an assembly object to Import-Module.

If you want to use -Assembly parameter you can use the following:
$assembly = [System.Reflection.Assembly]::LoadFrom('PowerShellXrm.Framework.CI.PowerShell.dll')
Import-Module -Assembly $assembly

Related

Powershell Loading Binary Module

I have few powershell script which I am trying to put into module. In the same module I also intend to load a c# dll for token generation. DLL uses System.Management.Automation.
#content of asr.psm1
Import-Module ".\tokengenerator\PowershellTokenGenerator.dll"
Get-ChildItem $psscriptroot\*.ps1 -Recurse | ForEach-Object { . $_.FullName }
The folder tokengenerator includes dll to generate OAuth2.0 token. How can I load powershell module and C# cmdlet under the same module. However, when I am trying to load the module I get the below error.
Import-Module D:\repo\src\aadsr\setup\asr.psm1
Import-Module : The specified module '.\tokengenerator\PowershellTokenGenerator.dll' was not loaded because no valid module file was found in any module directory. At D:\repo\src\aadsr\setup\asr.psm1:1 char:1
+ Import-Module ".\tokengenerator\PowershellTokenGenerator.dll"
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : ResourceUnavailable: (.\tokengenerato...enGenerator.dll:String) [Import-Module], FileNotFoundException
+ FullyQualifiedErrorId : Modules_ModuleNotFound,Microsoft.PowerShell.Commands.ImportModuleCommand
Use:
Import-Module "$PSScriptRoot\tokengenerator\PowershellTokenGenerator.dll"
to ensure that the DLL is found relative to the script module's (*.psm1) location, reflected in automatic variable $PSScriptRoot.
By contrast, if you use Import-Module ".\...", the DLL is looked for relative to the current location (.), whatever it may be.

Execute a PowerShell script from a Windows command prompt

I have the current version of 64 bit Windows 10 installed.
I can open a Windows PowerShell window and enter the following command to execute my PowerShell script. The script execute without error.
PS C:\Users\david\Desktop\test> ./messagebox.ps1
I want to execute the same script from a Windows Command Prompt window. When I enter the follow command, I get the displayed error messages.
C:\Users\david\Desktop\test>powershell -ExecutionPolicy Bypass -file messagebox.ps1
At C:\Users\david\Desktop\test\messagebox.ps1:81 char:14
+ Class Form : System.Windows.Forms.Form
+ ~~~~~~~~~~~~~~~~~~~~~~~~~
Unable to find type [System.Windows.Forms.Form].
At C:\Users\david\Desktop\test\messagebox.ps1:102 char:21
+ return [System.Windows.Forms.MessageBox]::Show($messsage, ...
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Unable to find type [System.Windows.Forms.MessageBox].
At C:\Users\david\Desktop\test\messagebox.ps1:108 char:21
+ return [System.Windows.Forms.MessageBox]::Show($messsage, ...
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Unable to find type [System.Windows.Forms.MessageBox].
+ CategoryInfo : ParserError: (:) [], ParentContainsErrorRecordException
+ FullyQualifiedErrorId : TypeNotFound
The script includes the following lines which I thought would include the correct assembly.
$n = new-object System.Reflection.AssemblyName("System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089")
[System.AppDomain]::CurrentDomain.Load($n) | Out-Null
You did not post enough code to actually reproduce the issue, but this works for me:
Add-Type -AssemblyName System.Windows.Forms | Out-Null
[System.Windows.Forms.MessageBox]::Show("Hello World")
I assume you can extend this to whatever version of Show() you need.
See also PowerShell Magazine

Problems trying to run Powershell code in command line (Load assembly)

I made some code that uses the New-Object command from the command line Powershell, but this error popped up whenever I tried to load anything from System.Windows:
PS C:\Users\USER> New-Object System.Windows.FontWeight
New-Object : Cannot find type [System.Windows.FontWeight]: verify that the assembly containing this type is loaded.
At line:1 char:1
+ New-Object System.Windows.FontWeight
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : InvalidType: (:) [New-Object], PSArgumentException
+ FullyQualifiedErrorId : TypeNotFound,Microsoft.PowerShell.Commands.NewObjectCommand
This code works fine in Powershell ISE:
PS C:\Users\USER> New-Object System.Windows.FontWeight
Normal
If anyone can tell me what the problem is and how to fix it, that would be greatly appreciated!
The problem is, that the assembly PresentationCore that contains type System.Windows.FontWeight is not loaded in your PowerShell session. Seems like PowerShell ISE and PowerShell Console do not preload the same assemblies. You can load the corresponding assembly as follows:
Add-Type -AssemblyName PresentationCore
PowerShell ISE loads the containing assembly on startup to build its own GUI.
In powershell.exe you'll have to load it yourself:
Add-Type -AssemblyName PresentationCore |Out-Null
The FontWeight Structure is present in the System.Windows namespace and PresentationCore assembly. As evident from the error, you need to add the assembly PresentationCore to your PowerShell command line. Use this and you will be good to go.
Add-Type -Assembly PresentationCore

Does #Requires work in module scripts?

Consider the following module script:
MyWebApp.psm1:
#Requires -Version 4
#Requires -Modules WebAdministration
function Test-MyWebApp() {
return ((Get-WebApplication 'myapp') -ne $null)
}
(Export-ModuleMember omitted for simplicity. The script still works as a module without it.)
If this were a ps1 script, the #Requires comments at the top would force PowerShell to throw an error if
The version were lower than 4
The WebAdministration module could not be loaded (imported)
But if I try to import this using Import-Module, do these have any effect? The #Requires documentation just says "scripts", but it doesn't clarify whether script modules count as "scripts" or not here. What can I do instead, if not?
No, it's treated as a normal comment
No, #Requires comments are not processed when a psm1 script is executed by calling Import-Module.
If we save the script in the question as both MyWebApp.psm1 and MyWebApp.ps1 on a machine that lacks the WebAdministration module, we get the following result:
PS> .\MyWebApp.ps1
.\MyWebApp.ps1 : The script 'MyWebApp.ps1' cannot be run because the following modules that are specified by the
"#requires" statements of the script are missing: WebAdministration.
At line:1 char:1
+ .\MyWebApp.ps1
+ ~~~~~~~~~~~~~~
+ CategoryInfo : ResourceUnavailable: (MyWebApp.ps1:String) [], ScriptRequiresException
+ FullyQualifiedErrorId : ScriptRequiresMissingModules
PS> Import-Module .\MyWebApp.psm1
PS>
Importing the module succeeds, and the function now exists in the current scope. But the function will fail:
PS> Test-MyWebApp
Get-WebApplication : The term 'Get-WebApplication' is not recognized as the name of a cmdlet, function, script file,
or operable program. Check the spelling of the name, or if a path was included, verify that the path is correct and
try again.
At .\MyWebApp.psm1:5 char:14
+ return ((Get-WebApplication 'myapp') -Eq $null)
+ ~~~~~~~~~~~~~~~~~~
+ CategoryInfo : ObjectNotFound: (Get-WebApplication:String) [], CommandNotFoundException
+ FullyQualifiedErrorId : CommandNotFoundException
Even the -Version check is ignored. If we bump it up to 5 on a machine with only PowerShell 4:
PS> .\MyWebApp.ps1
.\MyWebApp.ps1 : The script 'MyWebApp.ps1' cannot be run because it contained a "#requires" statement for Windows
PowerShell 5.0. The version of Windows PowerShell that is required by the script does not match the currently running
version of Windows PowerShell 4.0.
At line:1 char:1
+ .\MyWebApp.ps1
+ ~~~~~~~~~~~~~~
+ CategoryInfo : ResourceUnavailable: (MyWebApp.ps1:String) [], ScriptRequiresException
+ FullyQualifiedErrorId : ScriptRequiresUnmatchedPSVersion
PS> Import-Module .\MyWebApp.psm1
PS>
Use a Module Manifest
The only way to get the requirements validated properly is to use a module manifest. Unfortunately, this must be a separate file alongside the psm1 file. The following manifest will achieve what the #Requires comments are intended to do:
MyWebApp.psd1:
#
# Module manifest for module 'MyWebApp'
#
#{
ModuleVersion = '1.0'
PowerShellVersion = '4.0'
RequiredModules = #('WebAdministration')
RootModule = #('.\MyWebApp.psm1')
}
Importing this file gives the error we want:
PS> Import-Module .\MyWebApp.psd1
Import-Module : The required module 'WebAdministration' is not loaded. Load the module or remove the module from 'RequiredModules' in the file
'.\MyWebApp.psd1'.
At line:1 char:1
+ Import-Module .\MyWebApp.psd1
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : ResourceUnavailable: (.\MyWebApp.psd1:String) [Import-Module], MissingMemberException
+ FullyQualifiedErrorId : Modules_InvalidManifest,Microsoft.PowerShell.Commands.ImportModuleCommand
Unfortunately, you cannot declare the function in the same file. You must use a separate psd1 file and then explicitly declare the original psm1 script as the "root module." The root module is indicated as a path relative to the psd1 file.
Other attributes:
The ModuleVersion is required. It must be present.
PowerShellVersion accomplishes what #Requires -Version 4 intends.
RequiredModules accomplishes what #Requires -Modules WebAdministration intends.
Note that Test-MyWebApp is exported implicitly in both the psm1 and the psd1 file. This is normally controlled by Export-ModuleMember -Function in a psm1 file; the equivalent in a module manifest is FunctionsToExport. I find it simpler to just omit FunctionsToExport from the manifest and control what's exported using Export-ModuleMember in the psm1 script.

Compress folder using Powershell from SQLSERVER runtime

I need to zip a folder using powershell from within SQLPS runtime. I tried the following from PS SQLSERVER:\> prompt:
$dest = "C:\SomePath\FolderToBeZipped"
$zipfile = $dest + ".zip"
Add-Type -assembly "system.io.compression.filesystem"
[io.compression.zipfile]::CreateFromDirectory($dest,$zipfile)
When run, I get the below error :
Add-Type : Cannot add type. The assembly 'system.io.compression.filesystem' could not be found.
At C:\SomePath\Compress.ps1:10 char:9
+ Add-Type <<<< -assembly "system.io.compression.filesystem"
+ CategoryInfo : ObjectNotFound: (system.io.compression.filesystem:String) [Add-Type], Exception
+ FullyQualifiedErrorId : ASSEMBLY_NOT_FOUND,Microsoft.PowerShell.Commands.AddTypeComm
and
Add-Type : Cannot add type. One or more required assemblies are missing.
At C:\SomePath\Compress.ps1:10 char:9
+ Add-Type <<<< -assembly "system.io.compression.filesystem"
+ CategoryInfo : InvalidData: (:) [Add-Type], InvalidOperationException
+ FullyQualifiedErrorId : ASSEMBLY_LOAD_ERRORS,Microsoft.PowerShell.Commands.AddTypeCommand
But if I exit out of PS SQLSERVER:\> runtime and execute from normal PS command prompt it is able to compress successfully. Please help how to compress from SQLSERVER powershell runtime. I even tried to invoke a separate .ps1 script (for compressing) using Invoke-Expression from within PS SQLSERVER:\> runtime, but failed. Please help