Problems when loading Assemblies in PowerShell - powershell

I'm currently building a powershell transfer script that uses WinSCP assembly to upload files. I have defined a class in which I'm initializing things like the WinSCP.SessionOptions etc. These types are defined in the WinSCPnet.dll. At the beginning of my script I'm importing the assembly with
Add-Type -Path <Path-to-assembly.dll>
Later in my class definition I have a variable like this that is not yet initialized
[WinSCP.SessionOptions]$Script:SessionOptions
When I try to run the script I always get "Type not found" error referencing to the line where I'm declaring the uninitialized variable.
This problem is not limited to the WinSCP assemblies. I'm also getting it when I call a static method no matter if it's a system or a custom assembly.
What can I do to solve that?
Thanks in advance.

Related

Loading/use CsvHelper in PowerShell 7/.NET 5

Long story short - requesting assistance loading/using CsvHelper in PS 7 w/.NET 5. Dll loads fine but no exported commands available. Added a manifest (nested, root, etc) with full export didn't expose. Assistance would be greatly appreciated.
Long story long - Have a system with fairly vanilla installs of pwsh v7.1.3 and .NET v5.0.300. I've been assigned a project to work with very large CSV files and process them with SQLBULKCOPY. The files will have formatting challenges as well as date (datetime2) fun so a Csv parser seems to be the best course of action.
After seeing that CsvHelper can cut through the parsing requirements, is compiled for .NET 5 (no dependencies), and reading reviews showing 20%+ better performance than another DLL (lu...) being tested I would like to leverage it for the project.
This solution will be used on systems with no access to the internet and users with limited skills, so the hope is to use just include the CsvHelper dll in the script module directory.
Loading the CsvHelper.dll (net5.0) file import-module "...\CsvHelper.dll" appears to work. Get-Module shows the dll is loaded but doesn't show any exported commands. Get-Command doesn't either. I've tried creating a manifest file for the DLL (nestedmodules, rootmodule, etc. and export specific publics, *) but am unsuccessful. I'm sure I'm missing something simple and would appreciate assistance. Thanks much.
When I started this project the first test was using a Lumenworks parser. It can be loaded into PS and used directly. That was nice and it set my head in that specific direction. Moving into CsvHelper I was wanting (hoping) to stay in PS only. There were bureaucratic motivations to not to go into studio, compile a dll, and the like.
My hope was to load the helper dll in PS and then inline the C# code. Something along the lines of:
Import-Module "C:\...\CsvHelper.dll"
or
$Assem = (
<?? for csvhelper>
)
with
$source = #"
using CsvHelper;
<C# around using CsvHelper>
"#
and appropriate Add-Type
Add-Type -ReferencedAssemblies $Assem -TypeDefinition $Source -Language CSharp
What I wanted to do can probably be done but I don't have the skills for it. For now I'm going with a Studio project. Will build set it to do what I want, use it in PS for the solution and deal with the politics.
Appreciate the inputs.

New-CryptographyKey module Powershell

I have been working on a script and I needed to use Encryption/Decryption. Basically, encrypt a text file and then add the decryption code in my script and then let the script do its work by taking the encrypted file and decrypting it. After googling through stuff, I came across this post. By far it seemed the most simple implementation for my work. However, I am unable to import this module in my PS window.
When I write:
Import-Module New-CryptographyKey
I get the error:
Import-Module Cannot find path 'C:\WINDOWS\system32\New-CryptographyKey' because it does not exist.
I understand that this is some path issue but I have set the path in the environment.
Any suggestions will be helpful.
Your problem is how you're importing the module. Because the technet link you have in your question is directly to a .psm1 file, you need to fully-path that in your import command (as it does not have a proper module manifest):
Import-Module -Name 'C:\path\to\FileCryptography.psm1'
With this, it should work.
The alternative is you generate a module manifest, learn how module loading works and have the folder/files in the right location/named correctly, and then it can be auto-loaded on v3+, but that's a little outside the scope of this question.
So what I was missing was to importing the module as stated by TheIncorrigible1. After that, I was also missed adding the Assembly as follows in the Script.:
Add-Type -Assembly System.Security
Add-Type -AssemblyName System.Windows.Forms
How this worked is that I used the Technet link and understood what he was doing and used the assemblies that he imported in my script and extracted the Encrypting and the Decrypting statements he used. This seemed to work for me.
This happened because I was unable to Import the New-CryptographyKey because I was not specifying the path. So for anyone else, better to import the module with its path when you are facing this issue.
Thanks Incorrigible1 for letting me know of this, however I made this work in a noob way but the correct way to import it was by giving the correct path as
Import-Module -Name 'C:\path\to\FileCryptography.psm1'

Powershell import external DLL [duplicate]

I created a dll in C# and would like to use it in PowerShell.
I know I can load the dll using:
[Reflection.Assembly]::LoadFile("MyDll.dll")
But I don't want to use reflection.
Is there a simple way to do include my dll without reflection? Something like add reference to this dll?
In PowerShell 2.0 the cmdlet Add-Type is designed for this, for example:
Add-Type -Path "$env:Xyz\bin\Npgsql.dll"
(it’s more likely that under the covers it calls the same LoadFile but this way is more PowerShell-ish)

Determine difference between COM and .NET DLLs in Powershell

I'm writing a script to copy and move DLLs from the bin folder to a mapped drive, and I need to register/unregister the DLLs during the process. I've figured out how to do all of this, but there's a catch. The program I'm working on utilizes VB6 COM DLLs and VB.NET .NET DLLs. I understand that COM DLLs use regsvr32.exe, and .NET DLLs use regasm.exe, but I am interested in programmatically calling the correct function, based upon the DLL I am moving. Is there a way to determine what time I am using in Powershell?
Call
[Reflection.Assembly]::LoadFile( `mydll.dll`)
It should raise a BadImageFormatException if it is not a .Net dll.
As per MSDN:
"This exception is thrown when the file format of a dynamic link library (.dll file) or an executable (.exe file) does not conform to the format that is expected by the common language runtime. In particular, the exception is thrown under the following conditions:
...
An attempt is made to load an unmanaged dynamic link library or executable (such as a Windows system DLL) as if it were a .NET Framework assembly. The following example illustrates this by using the Assembly.LoadFile method to load Kernel32.dll."

Can't get powershell script to run inside PowerGUI

When I run my script directly from the Powershell console it works. When I run my script in PowerGUI and try instantiate an object, I get an error:
Exception calling ".ctor" with "3" argument(s): "Could not load file or assembly 'MyLib, Version=1.0.0.0, Culture=neutral, PublicKeyToken=77f676cc8f85d94e' or one of its dependencies. The system cannot find the file specified."
If I put all of the needed DLLs in $PSHOME, the script will successfully run from the console but not PowerGUI. If I move the DLLs to a local directory and load the DLLs with reflection, the script will not run in PowerGUI nor the powershell console.
[reflection.assembly]::loadfile('c:\mylibs\mylib.dll')
What do I need to do to get the script to run in PowerGUI? Ideally, I'd like the DLLs in a different directory than $PSHOME.
You should be using [Assembly]::LoadFrom as opposed to LoadFile. LoadFile is intended for loading assemblies that cannot be loaded in the normal assembly loading context such as the case where you are trying to load two versions of the same assembly. It does not use the normal probing rules so that is why it doesn't automatically load dependencies. Here's an excerpt from the documentation for LoadFile.
Use the LoadFile method to load and
examine assemblies that have the same
identity, but are located in different
paths. LoadFile does not load files
into the LoadFrom context, and does
not resolve dependencies using the
load path, as the LoadFrom method
does. LoadFile is useful in this
limited scenario because LoadFrom
cannot be used to load assemblies that
have the same identities but different
paths; it will load only the first
such assembly.
If you are using PowerShell 2.0 you may wish to use Add-Type instead:
Add-Type -Path c:\mylibs\mylib.dll
And if all else fails, run Fuslogvw.exe to find out why binding fails.
Use set-psdebug -trace 2 to see what it is attempting to call exactly.
This could be because PowerGUI is a different PowerShell host so its 'local folder' is PowerGUI's folder in Program Files, and not $pshome - where you put the DLLs.