Remotely start services with Powershell - c#

I have a Powershell script that starts a service on a remote machine.
It does something like this:
Invoke-Command -ComputerName $serverName -ScriptBlock { param($serviceexe) & $serviceexe -install }-ArgumentList $localExePath
It works OK in a local machine and also in Teamcity as a Build step.
But when I am trying to start the service from some other tool, I am getting the message:
"cannot start service from the command line or a debugger".
This other tool is written in C#, using System.Management.Automation.
I´ve also tried it using Process class, but still the same problem.
Any idea?

Have you considered Powershell Remote Requirements already?

Related

how to have a windows service self update?

All the solutions I can find on this topic are very old and none of them appear to answer my question...
I am trying to create a windows service that can self update (or auto update by some external trigger). In the past, I had created a windows service that was installed with InstallShield and we were able to update auto update the service in a hacky way by making the service write a batch script to the local machine and then run the batch script, which would stop the service, overwrite the service executable and other files with the new ones, and restart the service. This surprisingly worked.
However, I have updated the service to use InstallUtil.exe and this auto update script no longer works... I assume it's something to do with the way InstallShield handles the service install vs how InstallUtil does it... but I can only make guesses as I don't fully understand what each is doing to the registry.
Since I can't just overwrite the files and restart the service with the InstallUtil method, I thought I'd write a batch script that runs sc.exe to stop the service, uninstall it entirely, write the new files, install the new service files, and then start it... unfortunately, I can't seem to get sc.exe to run from a windows service automatically because it requires admin permissions... I tried to force it to self-elevate to admin using this snippet, but it doesn't appear to work as a service (it works fine if I run it from command line not as a service)
if not "%1"=="am_admin" (powershell start -verb runas '%0' am_admin & exit /b)
Does anyone know how I can cause a windows service to self update? I can look into updating to a .NET Core Worker service if there is some method of self update in .NET Core that I'm unaware of... Any ideas are much appreciated... it really shouldn't be this hard to accomplish...
For reference, here is the batch script I am currently using (ignore odd variables and such as I am dynamically replacing some of them, it works great when launched manually, just doesn't work when the service tries to run it):
#echo off
setlocal enableextensions enabledelayedexpansion
::make sure to run whole script as admin (this restarts scripts as admin if not already in admin mode)
if not "%1"=="am_admin" (powershell start -verb runas '%0' am_admin & exit /b)
pushd %networkDirectory%
::stop running service
for /F "tokens=3 delims=: " %%H in ('sc query %serviceName% ^| findstr " STATE"') do (
if /I "%%H" NEQ "STOPPED" (
net stop %serviceName%
if errorlevel 1 goto :stop
)
::delete existing service after stopping
sc delete %serviceName%
)
:: install updated service files
set "releaseDir=%networkDirectory%\Release"
set "programFilesCopyDir=%ProgramFiles%\{_companyDirectory}\%serviceName%\Release"
:: copy service Release dir to local system program files
xcopy "%releaseDir%" "%programFilesCopyDir%" /S /Y /Q
::execute the install
pushd "%programFilesCopyDir%"
CALL %serviceName%.exe --install
::start service
sc start %serviceName%
For anyone else trying to accomplish this that stumbles on this... I ended up finding a solution. I use the same script posted in my question above, but I wrote code to set up a scheduled task with Windows Task Scheduler. The scheduled task runs the above script as a one time scheduled task. This works like a charm.
I used this NuGet package to write the Task Scheduler code I needed:
https://www.nuget.org/packages/TaskScheduler/2.8.20?_src=template

Run powershell command from C# application

I would like to run the following powershell commands from my C# application:
Enter-PSSession –ComputerName fedsrv01.domain.local
Start-ADSyncSyncCycle -PolicyType Delta
I found some information on the Powershell Class but struggling to achieve what I want due to my lack of experience.
https://learn.microsoft.com/en-us/dotnet/api/system.management.automation.powershell?redirectedfrom=MSDN&view=pscore-6.2.0
This is what I have so far:
I have added the assembly and referenced system.management.automation
using (var powershell = PowerShell.Create())
{
//powershell.AddCommand("get-process");
powershell.AddCommand("Enter-PSSession -ComputerName fedsrv01.domain.local");
powershell.Invoke();
}
I get an error saying, 'The term 'Enter-PSSession -ComputerName fedsrv01.domain.local' is not recognized as the name of a cmdlet, function, script file, or operable program.
if I use: powershell.AddCommand("get-process") it executes fine.
If I launch Powershell on the same PC and enter, Enter-PSSession -ComputerName fedsrv01.domain.local it works fine.
Any assistance would be much appreciated.
Cheers,
Jono
Try compiling your application as x64. If it is compiled as x86 platform then it will be using the virtualized System32 dir so the function you require may not exist.
Powershell commands from C# 'the term is not recognizes as cmdlet'
Ok, after more research into the PowerShell class I now realise that you have to add the parameters separately using the .addparameter method.
.addcommand is just for the PowerShell commands. It now makes sense why I got the error saying the command could not be found. It was assuming the entire string was a command.
Problem solved!
Jono

The term 'Add-AzureAccount' is not recognized as the name of a cmdlet, function, script file

I am trying to use this azure commandlets form C# application that is console job hosted in my azure Virtual machine. this job runs more then once in a day automatically but my azure commandlets are fails to execute. yesterday that works fine but after a day it is not working please help me. ☺
Note : here i am doing some administration task and i am using organizational account. but it fails to add account other commandlets goes fail to work.
Install the Azure PowerShell tools. The download link is here: https://azure.microsoft.com/en-us/documentation/articles/powershell-install-configure/#how-to-install-azure-powershell
It's renamed to Add-AzureAccount.
I'm assuming that the original question was "The term 'Login-AzureRmAccount' is not recognized as the name of a cmdlet, function, script file. I'm seeing the same thing, despite "Install-Module AzureRM" having been done (from an elevated powershell prompt) and "Get-Module AzureRM" returning a version of 4.3.1 (i.e. powershell tools being installed).
The first part of the solution for me was to also do "Install-Module Azure" (from an elevated powershell prompt) as well after which "Add-AzureAccount" worked. However a command such as "New-AzureRmResourceGroup" still failed with "Run Login-AzureRmAccount to login".
The second part of the solution was simply to reboot, after which:
Add-AzureRmAccount
New-AzureRmResourceGroup -Name wibble -Location UKSouth
worked.

Run Exchange Powershell command from C#

I am trying to run EMC commands in C#. I am running this from my personal PC that has exchange management tools installed on it.
Our exchange servers have 2007 running on them.
The thing is, when I run Powershell or EMC, I need to run as a different user that has exchange server 2007 permissions since my individual profile doesn't have these permissions.
That being said, this is my code I have running on my personal PC:
RunspaceConfiguration config = RunspaceConfiguration.Create();
PSSnapInException snapEx = null;
PSSnapInInfo info = config.AddPSSnapIn("Microsoft.Exchange.Management.Powershell.Admin", out snapEx);
Runspace runspace = RunspaceFactory.CreateRunspace(config);
runspace.Open();
Command createCMD = new Command("Get-Mailbox ID");
Pipeline pipe = runspace.CreatePipeline();
pipe.Commands.Add(createCMD);
Collection<PSObject> results = pipe.Invoke();
The error I am getting is:
The Windows PowerShell snap-in Microsoft.Exchange.Management.Powershell.Admin is not installed on this computer.
I am getting it when I try and add the Microsoft.Exchange.Management.Powershell.Admin snapIn.
I feel this has something to do with my permissions on my individual profile, but I am not entirely sure. If it is true, how do I fix this.
EDIT
The reason I say it sounds like permissions is because I am able to open powershell and add the snapin. However when I run a command such as get-mailboxstatistics myUserId it throws an error saying MyServer\MyStorageGroup does not exist. However, when I shift-rightCLick and run as different user and use the credentials of my exchange admin account, I am able to run these commands.
If an error says it is not installed on your computer, why do you suspect it has something to do with permissions?
As this post suggests, please check if you have installed the 2007 version of the tools, as the Snapin in question is not available on the 2010 version.
Try the following steps:
Open up a powershell editor of your choice and add the PSSnapin there. If it works, the Snapin is available, if not, it is really not installed on your machine.
If it is available try to set your build configuration from x86 to 64bit or vice versa.
Eventually you can install the .dll in question by hand. Referring to this answer from Keith hill you have to issue the following Powershell commands
$snapinPath = 'Microsoft.Exchange.Management.PowerShell.Admin.dll'
C:\Windows\Microsoft.NET\Framework\v2.0.50727\InstallUtil.exe /i $snapinPath
Errors like this are often a 32 bit/64 bit problem. For example, the snapin might be registered as a 32 bit and your C# program is 64 bit or vice versa.
Sometimes you can fix this by running the other version of InstallUtil, e.g.
$snapinPath = 'Microsoft.Exchange.Management.PowerShell.Admin.dll'
C:\Windows\Microsoft.NET\Framework64\v2.0.50727\InstallUtil.exe /i $snapinPath
After fixing that, I think you'll hit another problem with how you're creating the command. You don't specify arguments when creating a command. Instead, you write something like:
Command createCMD = new Command("Get-Mailbox");
createCMD.Parameters.Add(null, "ID");

How to recycle an app pool on a remote machine using the command line

I have the following in a vbs file that i am trying to run from the command line:
strServerName = "ServerName"
strAppPoolName = "DefaultAppPool"
set objAppPools = GetObject("IIS://" & strServerName
& "/w3svc/AppPools/" & strAppPoolName & "")
objAppPools.Recycle()
And yet when I run the vbs from cmd line i get the following error:
Microsoft VBScript runtime error: ActiveX component can't create object: 'Get Object'_
I am running XP on my local machine, and the remote machine has IIS 7.
How can I get this to work?
I am not sure regarding the particular vb script but I would recommend using "appcmd" (http://learn.iis.net/page.aspx/114/getting-started-with-appcmdexe)
Add %windir%\system32\inetsrv to your path if it is not already
in a command prompt type: appcmd recycle apppool "apppool_name"
While not a vbs file command you could get vbs to execute this command line;
appcmd recycle apppool /apppool.name:string
The variable string is the name of the application pool that you want to recycle. For example, to recycle an application pool named Marketing, type the following at the command prompt, and then press ENTER:
appcmd recycle apppool /apppool.name:Marketing
Taken from technet
If it's too far away from what you want then my apologies.
Use powershell command to run it. Example:
Invoke-WMIMethod Recycle -Path "IIsApplicationPool.Name='W3SVC/APPPOOLS/apppoolname'" -Computer "WIN-Computername" -Namespace root\MicrosoftIISv2 -Authentication PacketPrivacy
Where apppoolname is your application pool name.
Where WIN-Computername is your remote/local server name
Use powershell to execute command remotely on the server:
Invoke-Command -ComputerName <YOUR_IIS_SERVER_NAME> -ScriptBlock { Restart-WebAppPool -Name <YOUR_APP_POOL_NAME> }
I just tried it from a Windows XP machine to Windows 2008R2 machine. It worked. So you are definitely on the right track.
If you are looking for an alternative way, try this from a command prompt. At least the error message will be a little more specific, when it doesn't work.
wmic /namespace:"\\root\MicrosoftIISv2" /node:"**serverName**" path IISApplicationPool where (name like '%**DefaultAppPool**%') call recycle
Have you got the IIS7 WMI Provider installed and enabled on the remote machine?
I think this doc covers most of what you need.
this covers pre req and how to browse the available management options...sure you'll be able to reset the app pool with a few tweaks...
I just stumbled upon this problem, and here's the fix:
There is a small windows tool called PsExec, which basically gives you command line remote access, and from there you can use apppool. You can just run this command from C#
psexec \\192.168.xx.xx %windir%\system32\inetsrv\appcmd recycle apppool /apppool.name:yourapppool
here's the tool: http://technet.microsoft.com/en-us/sysinternals/bb897553.aspx
Following commands worked for me after trying everything !
cd %windir%\system32\inetsrv
appcmd.exe stop site /site.name:"test1.com"
appcmd.exe start site /site.name:"test1.com"
Obviously before these, you will run some ssh remote command as well

Categories

Resources