Powershell Invoke error parameter number mismatch - powershell

Hello i want load a assembly from byte array and i found this:
Loading a .NET assembly from a byte array
It only loads .NET byte array.
And here is my code i changed it a little bit:
$ByteArray = (Invoke-WebRequest "https://DOTNETEXEfile.exe").Content
# Base64
$Base64String = [System.Convert]::ToBase64String($ByteArray);
$PsEBytes = [System.Convert]::FromBase64String($Base64String)
# Run EXE in memory
$assembly = [System.Reflection.Assembly]::Load($PsEBytes)
# Get the static method that is the executable's entry point.
# Note:
# * Assumes 'Program' as the class name,
# and a static method named 'Main' as the entry point.
# * Should there be several classes by that name, the *first*
# - public or non-public - type returned is used.
# If you know the desired type's namespace, use, e.g.
# $assembly.GetType('MyNameSpace.Program').GetMethod(...)
$entryPointMethod =
$assembly.GetTypes().Where({ $_.Name -eq 'Program' }, 'First').
GetMethod('Main', [Reflection.BindingFlags] 'Static, Public, NonPublic')
# Now you can call the entry point.
# This example passes two arguments, 'foo' and 'bar'
$entryPointMethod.Invoke($null, (, [string[]] ('foo', 'bar')))
But we have a problem, It works when i put my link of a c# project that has a msgbox and its .NET, its works fine but when i put a form app exe (.NET) it gives me that error:
PS C:\Users\sadettin\Desktop> C:\Users\sadettin\Desktop\PE.ps1
Exception calling "Invoke" with "2" argument(s): "parameter number mismatch."
At C:\Users\sadettin\Desktop\PE.ps1:25 char:1
+ $entryPointMethod.Invoke($null, (, [string[]] ('foo', 'bar')))
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : NotSpecified: (:) [], MethodInvocationException
+ FullyQualifiedErrorId : TargetParameterCountException
but when i replace $entryPointMethod.Invoke($null, (, [string[]] ('foo', 'bar'))) with $entryPointMethod.Invoke($null, $null) it works
Also when i put a exe (its not .NET) it doesn't work so is there have a way to execute all exe types?

Related

How to assign and reference environment variables containing square brackets in Powershell

When the PSDrive is not specified, the following works:
${[foo]}="bar"
echo ${[foo]}
But the following does not work
$env:${[foo]}="bar"
At line:1 char:1
+ $env:${[foo]}="bar"
+ ~~~~~
Variable reference is not valid. ':' was not followed by a valid variable name character. Consider using ${} to delimit the name.
At line:1 char:6
+ $env:${[foo]}="bar"
+ ~~~~~~~~~~~~~~
Unexpected token '${[foo]}="bar"' in expression or statement.
+ CategoryInfo : ParserError: (:) [], ParentContainsErrorRecordException
+ FullyQualifiedErrorId : InvalidVariableReferenceWithDrive
${env:[foo]}="bar"
Cannot find path 'env:[foo]' because it does not exist.
At line:1 char:1
+ ${env:[foo]}="bar"
+ ~~~~~~~~~~~~~~~~~~
+ CategoryInfo : ObjectNotFound: (env:[foo]:String) [], ItemNotFoundException
+ FullyQualifiedErrorId : PathNotFound
The following works, though I am curious if there's short hand syntax for it:
Set-Item -LiteralPath env:${[foo]} -Value "bar"
Get-Item -LiteralPath env:${[foo]} | % {$_.Value}
However the following does not work:
Set-Item -LiteralPath env:${[foo]2} -Value "bar"
Set-Item : Cannot process argument because the value of argument "name" is null. Change the value of argument "name" to a non-null value.
At line:1 char:1
+ Set-Item -LiteralPath env:${[foo]2} -Value "bar"
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : InvalidArgument: (:String) [Set-Item], PSArgumentNullException
+ FullyQualifiedErrorId : SetItemNullName,Microsoft.PowerShell.Commands.SetItemCommand
Written as of PowerShell Core 6.2.0
The reason is that PowerShell treats the following:
${<drive>:<name>}
as if you had specified:
Get-Content -Path <drive>:<name> # or, with assignment, Set-Content -Path ...
This notation - though often used with the Env: drive (e.g., $env:Path) - is little-known as a general paradigm named namespace variable notation, which is explained in this answer.
The problem is the use of -Path rather than -LiteralPath, because -Path interprets its argument as a wildcard expression.
Therefore, the [foo] in ${env:[foo]} - rather than being used as-is - is interpreted as a wildcard expression that matches a single character that is either f or o ([foo] is a character set or range ([...]) that matches any one of the (distinct) characters inside - see about_Wildcards).
On assigning to ${env:[foo]}, the logic of Set-Content -Path requires that a wildcard-based path resolve to something existing, even though you're generally not required to explicitly create environment variables; e.g., ${env:NoSuchVarExistsYet} = 'new' works just fine.
Workaround:
Use double(!)-`-escaping of the wildcard metacharacters:
# Namespace variable notation only works with if you
# double(!)-backtick-escape the wildcard metacharacters:
# Assign to / implicitly create env. var '[foo]'
${env:``[foo``]} = 'bar'
# Get its value.
${env:``[foo``]}
Note:
Escaping shouldn't be required at all, because there is no good reason to treat paths that conceptually identify a given, known item as wildcard expressions - see GitHub issue #9225.
That double `-escaping is needed is an added quirk - see GitHub issue #7999.
Another workaround - one that doesn't involve escaping - is to use
Set-Content -LiteralPath env:[foo] bar and Get-Content -LiteralPath env:[foo], but that is both verbose and slow.
As for the other syntax variations you tried:
$env:${[foo]}="bar"
Since your variable reference isn't {...}-enclosed as a whole (except for the initial $), the token that follows the : is only allowed to contain characters that do not require escaping - and $, { and } all violate that rule.
{...}-enclosing the entire path - ${env:[foo]} - solves the syntax problem, but runs into the problem detailed above.
Set-Item -LiteralPath env:${[foo]} -Value "bar"
This does not work in general, because string expansion is applied beforehand here - it is as if you had passed "env:${[foo]}": the reference to a (regular) variable named ${[foo]} is expanded (replaced with its value) and in effect appended to literal env:, before handing the result to Set-Item.
If such a regular variable doesn't exist, what Set-Item sees is just env: (because non-existent variables default to $null, which becomes the empty string in a string context), which causes an error due to the lack of variable name.
By contrast, the following would set an environment variable named unrelated instead:
# Create a regular variable literally named '[foo]'.
${[foo]} = 'unrelated'
# !! The following sets env:unrelated, i.e., env. var 'unrelated',
# !! due to the string expansion that is performed on the -LiteralPath
# !! argument up front.
Set-Item -LiteralPath env:${[foo]} bar
$env:unrelated # -> 'bar'
The same applies to Get-Item -LiteralPath env:${[foo]} and
Set-Item -LiteralPath env:${[foo]2} -Value "bar".

PowerShell error 'can't call null-value expresssion' [duplicate]

I am simply trying to create a powershell script which calculates the md5 sum of an executable (a file).
My .ps1 script:
$answer = Read-Host "File name and extension (ie; file.exe)"
$someFilePath = "C:\Users\xxx\Downloads\$answer"
If (Test-Path $someFilePath){
$stream = [System.IO.File]::Open("$someFilePath",[System.IO.Filemode]::Open, [System.IO.FileAccess]::Read)
$hash = [System.BitConverter]::ToString($md5.ComputeHash($stream))
$hash
$stream.Close()
}
Else{
Write-Host "Sorry, file $answer doesn't seem to exist."
}
Upon running my script I receive the following error:
You cannot call a method on a null-valued expression.
At C:\Users\xxx\Downloads\md5sum.ps1:6 char:29
+ $hash = [System.BitConverter]::ToString($md5.Compute ...
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : InvalidOperation: (:) [], RuntimeException
+ FullyQualifiedErrorId : InvokeMethodOnNull
To my understanding, this error means the script is attempting to do something, but another part of the script does not have any information to permit the first part of the script to work properly. In this case, $hash.
Get-ExecutionPolicy outputs Unrestricted.
What is causing this error?
What exactly is my null valued expression?
Any help is appreciated. I apologize if this is trivial and will continue my research.
References:
http://blogs.technet.com/b/heyscriptingguy/archive/2013/03/27/troubleshoot-the-invokemethodonnull-error-with-powershell.aspx
How to get an MD5 checksum in PowerShell
The simple answer for this one is that you have an undeclared (null) variable. In this case it is $md5. From the comment you put this needed to be declared elsewhere in your code
$md5 = new-object -TypeName System.Security.Cryptography.MD5CryptoServiceProvider
The error was because you are trying to execute a method that does not exist.
PS C:\Users\Matt> $md5 | gm
TypeName: System.Security.Cryptography.MD5CryptoServiceProvider
Name MemberType Definition
---- ---------- ----------
Clear Method void Clear()
ComputeHash Method byte[] ComputeHash(System.IO.Stream inputStream), byte[] ComputeHash(byte[] buffer), byte[] ComputeHash(byte[] buffer, int offset, ...
The .ComputeHash() of $md5.ComputeHash() was the null valued expression. Typing in gibberish would create the same effect.
PS C:\Users\Matt> $bagel.MakeMeABagel()
You cannot call a method on a null-valued expression.
At line:1 char:1
+ $bagel.MakeMeABagel()
+ ~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : InvalidOperation: (:) [], RuntimeException
+ FullyQualifiedErrorId : InvokeMethodOnNull
PowerShell by default allows this to happen as defined its StrictMode
When Set-StrictMode is off, uninitialized variables (Version 1) are assumed to have a value of 0 (zero) or $Null, depending on type. References to non-existent properties return $Null, and the results of function syntax that is not valid vary with the error. Unnamed variables are not permitted.

powershell function parameter types

have the following function:
function appendToSB([System.Text.StringBuilder]$sb,
[string]$value){
[void]$sb.append($value)
$sb
}
$sb = new-object -typename system.text.stringbuilder
$sb = appendToSb($sb, "1,")
$sb.tostring() | out-host
i want to build string using StringBuilder using my function for that, but i receive the following error:
appendToSB : Cannot process argument transformation on parameter 'sb'.
Cannot convert the "System.Object[]" value of ty pe "System.Object[]"
to type "System.Text.StringBuilder". At E:\powershell\test.ps1:8
char:11
+ appendToSb([system.text.stringbuilder]$sb, "1,")
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : InvalidData: (:) [appendToSB], ParameterBindingArgumentTransformationException
+ FullyQualifiedErrorId : ParameterArgumentTransformationError,appendToSB
does anybody can explain how function/function parameter/return values works in powershell?
Classic PowerShell issue. You don't use parens or comma separated args when calling commands or functions e.g.:
appendToSb $sb "1,"
You only use that syntax when calling .NET methods. If you use Set-StrictMode -Version 2 it will catch this sort of issue. What you passed ($sb, "1,") is how you would pass an array to a single parameter. Technically the parens aren't needed but don't change the value i.e. you could pass an array like this as well $sb, ",".

How to provide Linux-style parameter names in a powershell script

I would like to create a Powershell script that takes parameters in the standard Linux style, i.e., --my-param, with a leading --. I thought this might be possible using the alias parameter attribute, as in
Param (
[parameter(Mandatory=$true)]
[alias("-my-param","p")]
[String]
$param
)
What I hoped with this was that the call
c:\src\ps\params.ps1 --my-param "x"
would be recognized as referring to the alias -my-param. Unfortunately, what I get is
C:\src\ps\params.ps1 : A positional parameter cannot be found that accepts argument 'x'.
At line:1 char:21
+ c:\src\ps\params.ps1 <<<< --my-param1 "x"
+ CategoryInfo : InvalidArgument: (:) [params.ps1], ParameterBindingException
+ FullyQualifiedErrorId : PositionalParameterNotFound,params.ps1
On the other hand, using the alias my-param in this lets me call the script with -my-param.
Is there a way of specifying parameter names with leading -- in Powershell?
Your syntax fails at tokenizer level. Compare:
[Management.Automation.PSParser]::Tokenize(
'Command -parameter',
[ref]$null
)
...and...
[Management.Automation.PSParser]::Tokenize(
'Command --parameter',
[ref]$null
)
As you can see former is seen by parser as parameter, latter - as argument.
So the only way would be parsing all arguments "internally" and guessing what is parameter (from your perspective), and what is argument.
I'm not aware of any libraries that will parse Unix-style parameters for you (which doesn't necessarily mean there isn't one...), but you could just not declare any parameters, and parse the parameters yourself in the body of the script.
This will create a hashtable of the parameters, where they keys are the parameter names and the values are the parameter values. Switch parameters will have null values.
$params = #{}
$MyInvocation.Line.Substring(($MyInvocation.Line.IndexOf('--') + 2)) -split ' --' | %{
$_ -match '(\S+) ?(.+)?' | Out-Null
$params.($matches[1]) = $matches[2]
}
$MyInvocation.Line gives you the command line that was used to invoke the script. $MyInvocation.Line.Substring(($MyInvocation.Line.IndexOf('--') + 2)) gives you everything following the first --.
$_ -match '(\S+) ?(.+)?' assigns the parameter name to the first match group, and the value to the second match group. The Out-Null prevents PowerShell from printing True for each iteration.
The reason I used (.+)? rather than (.*) is to make the values of switch parameters null. (.*) will match an empty string if there is nothing to match, making the value of $matches[2] an empty string, whereas (.+)? won't match, making $matches[2] null.
This is assuming that all parameters begin with --. If you want to allow a single hyphen, restrict single-dash parameter names to a single letter, or check for incorrectly declared parameters (for example throw an error if there's a triple-hyphen), you'll have to account for that in your code, but this is the basic idea.

Why doesn't $hash.key syntax work inside the ExpandString method?

The following Powershell script demonstrates the issue:
$hash = #{'a' = 1; 'b' = 2}
Write-Host $hash['a'] # => 1
Write-Host $hash.a # => 1
# Two ways of printing using quoted strings.
Write-Host "$($hash['a'])" # => 1
Write-Host "$($hash.a)" # => 1
# And the same two ways Expanding a single-quoted string.
$ExecutionContext.InvokeCommand.ExpandString('$($hash[''a''])') # => 1
$ExecutionContext.InvokeCommand.ExpandString('$($hash.a)') # => Oh no!
Exception calling "ExpandString" with "1" argument(s): "Object reference not set to an instance of an object."
At line:1 char:1
+ $ExecutionContext.InvokeCommand.ExpandString('$($hash.a)')
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : NotSpecified: (:) [], MethodInvocationException
+ FullyQualifiedErrorId : NullReferenceException
Anyone know why the $hash.key syntax works everywhere but inside explicit expansion? Can this be fixed, or do I have to suck it up and live with the $hash[''key''] syntax?
I use this method, since this bug exists in v4 (not in v5)
function render() {
[CmdletBinding()]
param ( [parameter(ValueFromPipeline = $true)] [string] $str)
#buggy
#$ExecutionContext.InvokeCommand.ExpandString($str)
"#`"`n$str`n`"#" | iex
}
Usage for your example:
'$($hash.a)' | render
The ExpandString api is not exactly meant for use from PowerShell scripts, it was added more for C# code. It's still a bug that your example doesn't work (and I think it's been fixed in V4), but it does mean there is a workaround - one that I recommend for general use.
Double quoted strings effectively (but not literally) call ExpandString. So the following should be equivalent:
$ExecutionContext.InvokeCommand.ExpandString('$($hash.a)')
"$($hash.a)"
I was trying to store text that prompts the user in a text file. I wanted to be able to have variables in the text file that are expanded from my script.
My settings are stored in a PSCustomObject called $profile and so in my text I was trying to do something like:
Hello $($profile.First) $($profile.Last)!!!
and then from my script I was trying to do:
$profile=GetProfile #Function returns PSCustomObject
$temp=Get-Content -Path "myFile.txt"
$myText=Join-String $temp
$myText=$ExecutionContext.InvokeCommand.ExpandString($myText)
which of course left me with the error
Exception calling "ExpandString" with "1" argument(s): "Object
reference not set to an instance of an object."
Finally I figured out I only needed to to store the PSCustomObject values I want in regular old variables, change the text file to use those instead of the object.property version and everything worked nicely:
$profile=GetProfile #Function returns PSCustomObject
$First=$profile.First
$Last=$profile.Last
$temp=Get-Content -Path "myFile.txt"
$myText=Join-String $temp
$myText=$ExecutionContext.InvokeCommand.ExpandString($myText)
And in the text I changed to
Hello $First $Last!!!