I have a powershell script that automates the set up of PCs for a company. These PCs are not connected to any network when setting up and thus the script has to be manually transfered and started on each PC. The script has thus far been started with the help of a batch file which starts Powershell as admin with executionpolicy Bypass and works as intended.
However, i have created a simple GUI in C# WPF where the operator enters all the relevant information needed for the script to set up the PC. The script is then started from C# by running the batch file and it works, but there is a problem...
When starting from C# the script is not allowed to open secpol.msc to change some network policies. It does not recognize secpol.msc as a valid cmdlet. But, when the script is started via the batch file, or ISE, secpol.msc is a valid cmdlet. Below is the code used to start secpol.msc.
add-type -AssemblyName System.Windows.Forms
add-type -AssemblyName microsoft.VisualBasic
secpol.msc \
I get this error when starting from C# gui.
ERROR: An error has occurred [System.Management.Automation.CommandNotFoundException: The term 'secpol.msc' is not recognized as the name of a cmdlet, function, script file, or operable program.
Here is the code for the batch file.
#ECHO OFF
SET ThisScriptsDirectory=%~dp0
SET PowerShellScriptPath=%ThisScriptsDirectory%IPC-Bot-Main.ps1
PowerShell -NoProfile -ExecutionPolicy Bypass -Command "& {Start-Process PowerShell -ArgumentList '-NoProfile -ExecutionPolicy Bypass -File ""%PowerShellScriptPath%""' -Verb RunAs}";\
It does not seem that the script is allowed to change registry keys either.
I could work around the secpol.msc problem by opening gpedit.msc and navigating from there. But as it can't change registry keys either i have to solve this problem.
I'm suspecting that the script is opened in another scope when run from C# rather than the batch file.
Has anyone encountered this problem before or something similar?
EDIT:
Here is the C# code i use to run the batch file.
string strExeFilePath = System.Reflection.Assembly.GetExecutingAssembly().Location;
string path = System.IO.Path.GetDirectoryName(strExeFilePath);
Process.Start(path + #"\sources\StartAssist.bat");\
EDIT:
I think i should clarify, the C# GUI opens and runs just fine on the VM from the executable. And the script also starts as it should but the script does not have the same capabilities when starting from the GUI compared to when run from just the batch-file.
Thank you for all the comments and ideas! It made me think in different ways. Much appreciated!
It seems the problem was in the projects Build properties in C#. I Unchecked the option "Prefer 32-bit" and apparently that solved the issue.
If anyone has an idea as to why this could cause this issue i would love hear it.
Related
I have some custom powershell cmdlets in several scripts, one of which i've loaded an executed as such in C#
string Script2 = File.ReadAllText(#"C:\blabla\blabla\ScriptPowershell\TestCheck.ps1");
shell.Commands.Clear();
shell.AddScript(Script2, false);
shell.Invoke();
shell.Commands.Clear();
shell.AddCommand("TestCheck").AddParameter("ServerName", $"{serverId}").AddParameter("ServerPort", $"{serverPort}");
Collection<PSObject> psObjects = shell.Invoke();
The main issue with this is that if I publish and install this app on another computer that surely might not have this script at the same exact directory, the cmdlet will not work.
QUESTION : Is there a way to publish the app with the scripts joined to it, so that it doesn't need to search in the users computer for the scripts ? Or at least be present in the same directory as the .exe
Any suggestion to solve this problem is welcome.
Thank you !
Edit 1 : In response to #despacito this is the error message after appyling his solution
You can create a folder within your project to contain your scripts:
The path must be adjusted accordingly.
I have a PS script that has an import-module psmod1.psm1 statement.
Inside the PS script, I do a get-module and then write the names of all the loaded modules to a text file.
The script runs fine when run from pwsh on the CLI, and I see psmod1.psm1 written to the text file
I am invoking the script from within a .NET CORE C# application. This time the script runs fine but no module names get written to the text file (I am writing some other text to ensure the file itself is being successfully written to etc. and all that works fine).
So, since import-module inside the PS script did not appear to be working, I then added loading of the module to the C# code. This was done by using InitialSessionsState.CreateDefault() and then using ImportPSModule.
I still get the same results, it seems that for PS code invoked from within C# via RunSpaceFactory.CreateRunspace, it is impossible to import modules, either within the PS code file or from within C#. I have tested this on Windows 2008R2 as well as Windows 2012R2.
Due to some circumstances, I was ask to develop a page that uses Process in .Net C# to call the function through command prompt.
The code works perfectly Fine on visual studio, but when deployed on an IIS server. the Process doesn't seems to work, I've debugged and find out the process itself works. but the open Babel command doesn't work, i did double check and the identity i supply with should be alright, i did even supply it with admin privilege but still doesn't work. it doesn't even pop or error, it just simply ignored it and go through the commands.
I put the command into a .bat file, with some extra command to test if the .bat works. everything is fine until the command with open babel, then process just doesn't seem react with the command.
obabel %1 -O %2 --gen2d
this is the command i supply it with, %1 is the input file while %2 is the output file name. A very simple conversion. Note: everything is fine, just only the open babel command got ignored in the entire file. and I've tried to supply it with admin privilege, still doesn't work. the open babel can be used if directly used with command prompt on the server, or through visual studio. but it doesn't work if i deployed it through IIS server.
Found the solution, after all kinds of modification.
it seems like i have to provide a physical path to Open Babel.exe in the .bat file, and same as the parameter file i supply it with.
It's risky solution, but at least it solves the problem.
I am using a C# library I found that runs some remote Powershell scripts for Outlook Live. As a proof-of-concept that it works, I made a unit test that I can run (and step through for debugging) which merely calls a public static method inside this library which behind the scenes opens a remote Powershell session and runs a script.
This works just great in one of our Solutions, but it does not work when I run it in another Solution, even though both Solutions have the same two projects and test classes in them.. One Solution gives me an exception
There were errors in loading the format data file:
Microsoft.PowerShell, , C:\Users\xxxx.xxxx\AppData\Local\Temp\tmp_8c84e626-4399-420b-b874-9feeb3b1e195_tjlxhzzr.rlr\tmp_8c84e626-4399-420b-b874-9feeb3b1e195_tjlxhzzr.rlr.format.ps1xml : File skipped because of the following validation exception: File C:\Users\xxxx.xxxx\AppData\Local\Temp\tmp_8c84e626-4399-420b-b874-9feeb3b1e195_tjlxhzzr.rlr\tmp_8c84e626-4399-420b-b874-9feeb3b1e195_tjlxhzzr.rlr.format.ps1xml cannot be loaded because the execution of scripts is disabled on this system. Please see "get-help about_signing" for more details..
One attempt I made was to modify the PSCommand inside the C# library to have Unrestricted set and that did not solve the problem. However, if I open up the x86 Powershell and run set-executionpolicy Unrestricted my test will run in both Solutions. Changing the execution policy in the x64 version of Powershell had no effect on either Solution.
Is there some type of setting for permissions that is specific to a Solution? Neither the Web.Config or Global.asax should matter since I'm not loading any pages, so I don't know what else would take effect since I'm running the same unit test in both solutions with the same test runner (Testdriven.Net).
Any ideas? Thanks.
Run as administrator usually sets hklm otherwise it is set in hkcu
on a 64bit OS you need to run Set-ExecutionPolicy for 32bit and 64bit PSH separately
HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\PowerShell\1\ShellIds\Microsoft.PowerShell
to check
cd "hklm:\Software\Microsoft\Powershell\1\ShellIds\Microsoft Powershell"
dir
I've been scratching my head on this one for a while and cannot seem to find anything. I am trying to execute the following:
C:\Windows\Microsoft.NET\Framework\v3.5\MsBuild.exe D:\SourceFiles\Testing\AppaloosaDotNet\AppaloosaDotNet\AppaloosaDotNet.csproj "/t:_CopyWebApplication;ResolveReferences;publish" /p:ReferencePath=D:\Builds\Testing\LatestBuild\ /p:OutDir=\\ServerName\D$\WebContent\AppaloosaDotNET\bin\ /p:WebProjectOutputDir=\\ServerName\D$\WebContent\AppaloosaDotNET\
If I type this command directly into the PowerShell prompt it works fine. However I have created a PowerShell script that makes this call for me and when the script executes, MSBuild moves up one folder and uses the solution file (.sln) to build the project. This causes problems because the targets are not found in the solution file.
If I manually type the command and execute it MSBuild prints out it is building D:\SourceFiles\Testing\AppaloosaDotNET\AppaloosaDotNET\AppaloosaDotNET.csproj and the build is fine.
but if I run the script MSBuild prints out it is building D:\SourceFiles\Testing\AppaloosaDotNET\AppaloosaDotNET.sln and then the build fails because the targets are not found.
I'm sure I'm doing something wrong in my script but cannot figure out what. I have double checked to see that the command executed by the script is the same as I what I type. I even copied the command that is run when running the script and pasted at the prompt and it runs fine so I'm pretty sure the commands are the same. Any ideas?
Could your script be located at the same path as your solution?
How exactly are you running your script and where does it reside (if it's not on the same path as solution)?
It could be nothing but let's just confirm.
Just an update. I started having more issues with the script but finally have found a solution. I was building the command line using string variables inside the script. Initially the script was executing the command using the & operator. I ended up using the Invoke-Expression command and the problems were solved.