Powershell null pointer exception - powershell

I've been working on and off on a project to compress and move files older than x days to an archival folder. I've retrofitted the script here: https://gallery.technet.microsoft.com/scriptcenter/PowerShell-Compress-Log-121e63b5 to assist me however I'm running into an issue that has proved fairly annoying.
When I run this on my machine, utilizing local directories, the script completes as expected. However, when I pass networked file paths to the script, the Get-WmiObject query begins returning null results.
For example, this is a sample command line that works:
powershell -executionpolicy remotesigned -File compress_and_move_files.ps1 c:\temp\ c:\temp\compress_test\ 14
When I move to a UNC path, I begin getting the null-valued expression error on the WMIQuery.Compress() call
powershell -executionpolicy remotesigned -File compress_and_move_files.ps1 \\server1\temp\ \\server1\temp\compress_test\ 14
This is the full error:
You cannot call a method on a null-valued expression.
At compress_and_move_files.ps1:14 char:23
+ If ($WMIQuery.Compress <<<< ()) {Write-Host "$FullName compressed successfull
y."-ForegroundColor Green}
+ CategoryInfo : InvalidOperation: (Compress:String) [], RuntimeE
xception
+ FullyQualifiedErrorId : InvokeMethodOnNull

That script attempts to retrieve a CIM_DataFile instance - a class that isn't accessible via UNC paths in WMI.
Change the script to target the remote computer and then use the local file system path:
$Server = "server1"
$WMIFile = "C:\temp\".Replace("\", "\\")
$WMIQuery = Get-WmiObject -Computer $Server -Query "SELECT * FROM CIM_DataFile WHERE Name='$WMIFileName'"

Related

How to use ".\" in -file in a command file

I need to execute a command file (B.cmd) on Machine B from a Powershell script (A.ps1) on Machine A. I don't want to statically specify the path
B.cmd is supposed to execute C.ps1 which is in the same folder as B.cmd
MACHINE A: A.ps1
MACHINE B: B.cmd, C.ps1 (all in same folder)
so my command file looks like this B.cmd
#echo off
powershell.exe -file ".\C.ps1" -Iterations 10
echo
echo
pause
There's an error thrown in a A.ps1 file from which I'm calling the B.cmd file
A.ps1
Invoke-Command -ComputerName $systemName -credential $credentials -ScriptBlock {Invoke-Expression -Command: "cmd.exe /c C:\Temp\Batch\Test\B.cmd"}
A.ps1 throws error:
**The argument '.\C.ps1' to the -File parameter does not exist. Provide the path to an existing '.ps1' file as an argument to the -File parameter.**
+ CategoryInfo : NotSpecified: (The argument '....File parameter.:String) [], RemoteException
+ FullyQualifiedErrorId : NativeCommandError
+ PSComputerName : XXX
How do I make the .\ work or is there an alternative or is it wrong to use the .\ for a remote execution ?
Please forgive my ignorance anywhere as I'm very very new to PS, Thank You !
If you're able to change the ABC.cmd you could use the following
powershell.exe -file "%~dp0\XYZ.ps1"
This will get the folder the ABC.cmd script is running from. Note that %~dp0 won't work in cmd for testing you'll need to test it from within a script.
So don't wrap a batch file around it. A waste of time and confuses the issue.
invoke-command -comp $computername -filepath C:\Temp\Batch\Test\XYZ.ps1
If you need to run something 10 times, do it in a loop inside your PS script.

How to run PowerShell Invoke-Command from Command Prompt when the script has a switch?

I have the need to run PowerShell scripts using the command prompt (calling powershell.exe with the -c parameter). I have run these for years but have never tried it with Invoke-Command in order to do remoting and when the script I want to execute has a switch I have to pass.
This piece of code works great from PowerShell, a simple script that has the LogRun switch:
icm -cn MYCOMPUTER02 {C:\Temp\Write-to-File.ps1 -LogRun $Using:LogRun}
However, when I run it via the Command Prompt with powershell.exe fails:
powershell -c "icm -cn MYCOMPUTER02 {C:\Temp\Write-to-File.ps1 -LogRun $Using:LogRun}"
I have tried many variations of this and nothing works, I am sure I missing some syntax detail or some quotes somewhere.
Please let me know if you can help me figure this out.
This is the error I get:
icm : The value of the using variable '$using:LogRun' cannot be retrieved
because it has not been set in the local session.
At line:1 char:1
+ icm -cn MYCOMPUTER02{D:\PatV2DU\PatV2DUService20180411120032\Sc ...
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : InvalidOperation: (:) [Invoke-Command], RuntimeException
+ FullyQualifiedErrorId : UsingVariableIsUndefined,Microsoft.PowerShell.Commands.InvokeCommandCommand

How do I run a *.exe file from PowerShell

I have a folder at C:\Folder that has files input.xml, output.xml and licensegenerator.exe. Licensegenerator.exe takes variables that we put into input.xml and creates a temporary license for one of our programs using the output.xml file. We typically do this via command line by navigating to the C:\Folder directory, then running the command:
LicenseGenerator.exe "C:\Folder\input.xml" "C:\Folder\output.xml"
I'm attempting to write a script to do the exact same thing in PowerShell, but I'm struggling... Here's what I have:
$inputtest = "C:\Folder\Input.xml"
$outputtest = "C:\Folder\Output.xml"
$licensegen = "C:\Folder\LicenseGenerator.exe"
Invoke-Command $licensegen "$inputtest" "$outputtest"
When I run this, I get the error:
Invoke-Command : A positional parameter cannot be found that accepts argument
'C:\Folder\Output.xml'.
At line:5 char:1
+ Invoke-Command $licengegen "$inputtest" "$outputtest"
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : InvalidArgument: (:) [Invoke-Command], ParameterBindingException
+ FullyQualifiedErrorId : PositionalParameterNotFound,Microsoft.PowerShell.Commands.InvokeCommandCommand
I have also tried running with Invoke-Expression but get the exact same error (except it says "Invoke-Expression" at the beginning). Anybody have any idea what I'm doing wrong here?
You're looking for the call operator (&):
& $licensegen "$inputtest" "$outputtest"
Invoke-Command is essentially for running scriptblocks on other hosts and/or in other user contexts.
Start-Process
is great because you can runas, redirect output, hide the child processes window and much more.
Start-Process -FilePath $licensegen -Argumentlist $inputtest,$outputtest
& "[path] command" [arguments]
Just replace Invoke-Command with &

MSBTS_HostSetting is Not Found

Upon building a script to automate the deletion of Host and Host Instances, I run the script below in PowerShell.
PS
C:\WINDOWS\system32>
[System.Management.ManagementObject]$objHostSetting =
([WmiClass]"root/MicrosoftBizTalkServer:MSBTS_HostSetting").Delete()
However, after running the script, it seems that the MSBTS_HostSetting is gone because I was receiving the error below every time I am running it.
PS
C:\WINDOWS\system32>
[System.Management.ManagementObject]$objHostSetting
=[WmiClass]"root/MicrosoftBizTalkServer:MSBTS_HostSetting" Cannot convert value "root/MicrosoftBizTalkServer:MSBTS_HostSetting" to type
"System.Management.ManagementClass". Error: "Not found " At line:1
char:2
+ [System.Management.ManagementObject]$objHostSetting =[WmiClass]"root/MicrosoftB ...
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : InvalidArgument: (:) [], RuntimeException
+ FullyQualifiedErrorId : InvalidCastToWMIClass
I am trying to load the BizTalkOMExplorer but the MSBTS_HostSetting has not returned. Any suggestions or knowledge how can I bring it back.
Just fixed my issue! Below are what I've done.
Open CMD and register the BTSWMIProvider.dll
Example:
Regsvr32.exe “C:\Program Files (x86)\Microsoft BizTalk Server 2013 R2\Bins32\BTSWMIProvider.dll“
Run the following in CMD as well.
mofcomp.exe BTSWMISchema.mof
mofcomp.exe BTSWMISchema.mfl
Restart WMI in services.
This would do the trick! :)
With PowerShell, you can get your HostInstances as:
$hostInstances = Get-WmiObject MSBTS_HostInstance -namespace root\MicrosoftBizTalkServer -ErrorAction Stop
And then you can find which one you want to delete and invoke Delete method:
$hostInstances[0].Delete()
The same with Hosts:
$hosts = Get-WmiObject MSBTS_Host -Namespace root\MicrosoftBizTalkServer -ErrorAction Stop
$hostToDelete = $hosts | where {$_.Name -eq 'HostNameToDelete'}
$hostToDelete.Delete()

Powershell: Running a .msc applet as another user

I'm currently writing a powershell script that asks for a single set of admin credentials, and uses those to run relevant applications, pulled from a network-hosted CSV. When I try to run
Start-Process $tools[$userInput-1].path.toString() -credential $credential
(where $tools is returning "C:\Program Files\Microsoft\Exchange Server\V14\Bin\Exchange Management Console.msc") I get the error below
Start-Process : This command cannot be executed because the input "C:\Program Files\Microsoft\Exchange Server\V14\Bin\Exchange Management Console.msc" is an Invalid Application. Give a valid application and Run your command again.
At line:1 char:14
+ Start-Process <<<< "C:\Program Files\Microsoft\Exchange Server\V14\Bin\Exchange Management Console.msc" -credential
Get-Credential
+ CategoryInfo : InvalidOperation: (:) [Start-Process], InvalidOperationException
+ FullyQualifiedErrorId : InvalidOperationException,Microsoft.PowerShell.Commands.StartProcessCommand
If I need to, I'll just write a .bat file and run that, but I'd rather avoid that whenever possible.
And the reason I'm not using Invoke-Item is because it can't take -Credential, even if the man file says otherwise.
.msc is a saved console file, the host of which is mmc, so to start this from powershell you could use syntax similar to the following:
$mmcPath = "C:\Windows\System32\mmc.exe"
$mscPath = "C:\Program Files\Microsoft\Exchange Server\V14\Bin\Exchange Management Console.msc"
Start-Process -FilePath $mmcPath -ArgumentList $mscPath