PowerShell 5 class: Import module needed for type - powershell

I have a written a PowerShell 5 class:
class ConnectionManager
{
# Public Properties
static [String] $SiteUrl
static [System.Management.Automation.PSCredential] $Credentials
static [SharePointPnP.PowerShell.Commands.Base.SPOnlineConnection] $Connection
...
}
The type "SharePointPnP.PowerShell.Commands.Base.SPOnlineConnection" is from a custom (installed module), named "SharePointPnPPowerShell2016"
My class is inside another module/file, called "connection.manager.psm1".
When I load this module to make use of this class, it returns me the following error:
> Import-Module connection.manager.psm1
At connection.manager.psm1:6 char:11
+ static [SharePointPnP.PowerShell.Commands.Base.SPOnlineConnection] ...
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Unable to find type
[SharePointPnP.PowerShell.Commands.Base.SPOnlineConnection].
When I manually load the (PNP) module in the PowerShell session before loading my module it is loaded correctly and I can use it.
But I don't want to always have to manually load the other module first before I use my module. I tried to import the PNP-Module directly inside my module by adding:
Import-Module "SharePointPnPPowerShell2016"
at the beginning, before the class declaration, but it changes nothing, the error "Unable to find type" still appears.
Any ideas how to do this correctly?

I think you can fix this problem by using a module manifest
There is a "Required Module" and a "required Assembly" section you could use. This should handle loading the requirements (as long as they are installed) when you load your custom module, which holds the class.

If you have declared a class in a module, you cannot use it if you Import-Module; that only brings in cmdlets, functions, and aliases. Instead, your script should Using module the module; that will bring in the class as well as the other exported items.
(I actually misread the problem; this does not work to solve the querent's specific problem - but for a class that does not use classes from other modules, this will allow importing of classes from modules. The querent has found a known issue in PowerShell; see the comments for further information.)

Related

Deno: unable to import a library which contains relative imports

I'm trying to write some code that uses Deno and rdflib. And failing miserably.
Here's my test program:
// #deno-types="https://dev.jspm.io/npm:rdflib#2.2.7/lib/index.d.ts"
import { Namespace } from 'https://dev.jspm.io/npm:rdflib#2.2.7/lib/index'
when I ask deno to cache the remote packages, it fails:
$ deno --unstable cache rdflib.ts
Check file:///home/ian/projects/personal/deno-experiments/rdflib.ts
error: TS2502 [ERROR]: 'thisArg' is referenced directly or indirectly in its own type annotation.
bind<T>(this: T, thisArg: ThisParameterType<T>): OmitThisParameter<T>;
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
at asset:///lib.es5.d.ts:350:22
TS2614 [ERROR]: Module '"https://dev.jspm.io/npm:rdflib#2.2.7/lib/query"' has no exported member 'Query'. Did you mean to use 'import Query from "https://dev.jspm.io/npm:rdflib#2.2.7/lib/query"' instead?
import { Query } from './query';
~~~~~
at https://dev.jspm.io/npm:rdflib#2.2.7/lib/index.d.ts:16:10
TS2614 [ERROR]: Module '"https://dev.jspm.io/npm:rdflib#2.2.7/lib/updates-via"' has no exported member 'UpdatesSocket'. Did you mean to use 'import UpdatesSocket from "https://dev.jspm.io/npm:rdflib#2.2.7/lib/updates-via"' instead?
import { UpdatesSocket } from './updates-via';
~~~~~~~~~~~~~
at https://dev.jspm.io/npm:rdflib#2.2.7/lib/index.d.ts:26:10
TS2614 [ERROR]: Module '"https://dev.jspm.io/npm:rdflib#2.2.7/lib/updates-via"' has no exported member 'UpdatesVia'. Did you mean to use 'import UpdatesVia from "https://dev.jspm.io/npm:rdflib#2.2.7/lib/updates-via"' instead?
import { UpdatesVia } from './updates-via';
~~~~~~~~~~
at https://dev.jspm.io/npm:rdflib#2.2.7/lib/index.d.ts:27:10
TS2749 [ERROR]: 'Store' refers to a value, but is being used as a type here. Did you mean 'typeof Store'?
at https://dev.jspm.io/npm:rdflib#2.2.7/lib/index.d.ts:32:32
... many more lines ...
TS2614 [ERROR]: Module '"https://dev.jspm.io/npm:rdflib#2.2.7/lib/utils/termValue"' has no exported member 'termValue'. Did you mean to use 'import termValue from "https://dev.jspm.io/npm:rdflib#2.2.7/lib/utils/termValue"' instead?
export { termValue } from './utils/termValue';
~~~~~~~~~
at https://dev.jspm.io/npm:rdflib#2.2.7/lib/index.d.ts:40:10
Found 44 errors.
As far as I can tell, the problem is with lines in the remote code that do relative imports. Do such relative imports not work with Deno, or am I missing some vital step, or is my approach doomed?
Version info:
$ deno --version
deno 1.12.2 (release, x86_64-unknown-linux-gnu)
v8 9.2.230.14
typescript 4.3.5
The problem is not that they are relative specifiers, but that they are not fully qualified. From section 6.6 in the manual:
Can I use TypeScript not written for Deno?
Maybe. That is the best answer, we are afraid. For lots of reasons, Deno has chosen to have fully qualified module specifiers. In part this is because it treats TypeScript as a first class language. Also, Deno uses explicit module resolution, with no magic. This is effectively the same way browsers themselves work, though they don't obviously support TypeScript directly. If the TypeScript modules use imports that don't have these design decisions in mind, they may not work under Deno.
Also, in recent versions of Deno (starting with 1.5), we have started to use a Rust library to do transformations of TypeScript to JavaScript in certain scenarios. Because of this, there are certain situations in TypeScript where type information is required, and therefore those are not supported under Deno. If you are using tsc as stand-alone, the setting to use is "isolatedModules" and setting it to true to help ensure that your code can be properly handled by Deno.
One of the ways to deal with the extension and the lack of Node.js non-standard resolution logic is to use import maps which would allow you to specify "packages" of bare specifiers which then Deno could resolve and load.

Check for empty file and quit cakebuild

I am attempting to write a check in my Cake build script to pull in a file from BuildParameters and check if the file contents are empty -- if contents are empty, throw an exception and quit the build.
I am attempting to use FileReadText from the FileHelpers namespace but for some reason I cannot get my build to recognize the file command. I am following the syntax and documentation found here: https://cakebuild.net/api/Cake.FileHelpers/FileHelperAliases/97F5679A
Here is the code I am trying in build.cake:
var fileReadText= FileReadText(Parameters.TestParameters.TestListFP);
var fileText= fileReadText.ThrowIfNullOrEmpty(nameof(fileReadText));
The argument Parameters.TestParameters.TestListFP is set in my Parameters.cake file as such:
TestListFP = context.File("C:\Some\Path\some_file_name.txt");
Using the above code, I see this error:
error CS0103: The name 'FileReadText' does not exist in the current
context
Note that I do not have a ICakeContext in build.cake, just BuildParameters.
I tried to resolve the issue by adding using Cake.FileHelpers; at the top of my build.cake file, but then I see this error:
The type or namespace name 'FileHelpers' does not exist in the namespace 'Cake' (are you missing an assembly reference?)
The script works fine without my FileReadText code, so I know TestListFP is actually a valid file.
I think I am inherently misunderstanding how to use FileHelpers and FileReadText and I could not find any examples of usage in documentation or anywhere else. If anyone has guidance on how to use this method, or a better way to accomplish what I am trying to do, I would appreciate the help.
Have you added the #addin pre-processor directive, as mentioned here:
https://github.com/cake-contrib/Cake.FileHelpers/#cakefilehelpers
You can easily reference Cake.FileHelpers directly in your build script via a cake addin:
#addin "Cake.FileHelpers"

Powershell Classes constructor called twice - using module and Import-Module

Update:
Scary scary, restarting the computer helped.
I will keep it, if someone encounter this.
Setup:
Powershell version: 6.2.1
MacOs: Catalina
I am using Classe, so I have to use "using module" to be able to reference classes.
I am also using "Import-Module" to load modules.
But now i get some strange behaviour - class constructer called twice and same file opened twice in VSCode.
Loading:
Import-Module module_one.psm1
Import-Module module_two.psm1
In module_one.psm1:
Class MyClass {
MyClass(){} # << This is called twice
}
In module_two.psm1:
using module module_one.psm1
[MyClass]::new()
Is there no way to use Classes with "Import-Module"?

using module $PSScriptRoot: is not a valid value for using name

How do you use using module with $PSScriptRoot?
using module $PSScriptRoot/../myfolder/base.psm1
# or: using module "$PSScriptRoot/../myfolder/base.psm1"
If I do this, I get this error:
using module $PSScriptRoot: is not a valid value for using name
Thanks to #DavidBrabant I have tried the following:
$scriptBody = "using module /Users/name/Development/tools/powershell/base/base.psm1"
$script = [ScriptBlock]::Create($scriptBody)
. $script
Class Go : MyBaseClass {
...
Unfortunately I get:
Unable to find type [MyBaseClass].PowerShell
Ignoring 'TypeNotFound' parse error on type 'MyBaseClass'. Check if the specified type is correct. This can also be due the type not being known at parse time due to types
Thanks to and #MathiasR.Jessen I tried with "\" with same result. I should say that I am on a mac computer if that makes any different.
This answer is based on David's comment on the question.
"To use variable values in a Using module statement, create a script block that includes the Using module statement and dot-source it into the script. (Thanks to Bartek Bielawski for this solution.)"
Param (
[parameter(Mandatory)]
[string]
$ModuleName
)
$scriptBody = "using module $ModuleName"
$script = [ScriptBlock]::Create($scriptBody)
. $script
...
SOURCE: https://info.sapien.com/index.php/scripting/scripting-classes/import-powershell-classes-from-modules

Could not load file or assembly(dll file path+name) or one of its dependencies. An attempt was made to load a program with an incorrect format

When trying to perform-
Import-Module 'C:\\Program Files\\Nimble Storage\\bin\\Nimble.Powershell.dll'
through program, I am receiving below error:
Could not load file or assembly 'file:///C:\Program Files\Nimble
Storage\bin\Nimble.Powershell.dll' or one of its dependencies. An
attempt was made to load a program with an incorrect format.
The same works when ran directly from Powershell but in the above case, facing issue.
C# program used and have used statement:
Collection< PSObject > resultCollection = runspaceInvoke.Invoke("Import-Module 'C:\\Program Files\\Nimble Storage\\bin\\Nimble.Powershell.dll'", null, out errors);
EBGreen is right. Need to see your code bro. In absence of that, something like the following should work:
using System.Management.Automation;
using System.Management.Automation.Runspaces;
class foo {
static void Main(string[] args) {
InitialSessionState initial = InitialSessionState.CreateDefault();
initial.ImportPSModule(new string[] {"'C:\\Program Files\\Nimble Storage\\bin\\Nimble.Powershell.dll'"} );
...
}
}
Check out Creating an InitialSessionState for more information.