Link to home
Start Free TrialLog in
Avatar of jenny zhou
jenny zhou

asked on

c# script task to check a service

i wrote c# script task to check a service is running on a remote server, but running the task generated error which doesn't really tell what's the real problem.
Avatar of Chinmay Patel
Chinmay Patel
Flag of India image

Just like this question, it doesn't really tell what's the real error, leaving us to guess the error.

On a serious note, could you please post error details (if the error details are not shown by the script, you can check log files or windows event log)
Avatar of slightwv (䄆 Netminder)
slightwv (䄆 Netminder)

My question would be:
Why write your own code for this when PowerShell already has it?

Look at Get-Service and the -CompterName parameter.
Avatar of jenny zhou

ASKER

we are not allowed to use PowerShell so have to use script task.
Post your C# code please
this is the error:

   at System.RuntimeMethodHandle.InvokeMethod(Object target, Object[] arguments, Signature sig, Boolean constructor)
   at System.Reflection.RuntimeMethodInfo.UnsafeInvokeInternal(Object obj, Object[] parameters, Object[] arguments)
   at System.Reflection.RuntimeMethodInfo.Invoke(Object obj, BindingFlags invokeAttr, Binder binder, Object[] parameters, CultureInfo culture)
   at System.RuntimeType.InvokeMember(String name, BindingFlags bindingFlags, Binder binder, Object target, Object[] providedArgs, ParameterModifier[] modifiers, CultureInfo culture, String[] namedParams)
   at Microsoft.SqlServer.Dts.Tasks.ScriptTask.VSTATaskScriptingEngine.ExecuteScript()

Open in new window

ServiceController sc = new ServiceController();

            
            sc.MachineName = "APP01.company.com";
            sc.ServiceName = "AutomationServices";

           
            if (sc.Status.ToString().ToLower() == "running")       
            {

                Dts.Variables["ServiceStatus"].Value = "Running";

            }

Open in new window

might it be because of permission issue, so can't use ServiceController? i'm testing it on SSIS from Visual Studio on my local machine.
VS running as admin?
tried various ways and nothing worked. I'm not a c# programmer, just need to use it in SSIS script task.
     
            string ServerName = "APP01.company.com";
            string ServiceName = "AutomationServices";

            try
            {

                ServiceController sc = new ServiceController(ServiceName, ServerName)

                if (sc.Status.ToString().ToLower() == "running")
                {
                    Dts.Variables["ServiceStatus"].Value = "Running";
                }
            }
            catch
            {
                Dts.Variables["ServiceStatus"].Value = "Not Running";
            }
I tried by using PowerShell which worked but we can't use it after deploying to production server due to security concern. DBA required us to use SSIS script task.

$servers = "APP01.company.com", "APP02.company.com", "APP03.company.com", "APP04.company.com"
$log = New-Item -type file -force “\\FileServer\Staging\ServerProcessStatus\ServiceStatus.csv”
$Logtime = Get-Date -Format “MM-dd-yyyy hh-mm-ss”

foreach ($server in $servers) {
    $status = (get-service -Name AutomationServices -ComputerName $server).Status
    if ($status -eq "Running") {
        Write-output “AutomationServices is running: ${Logtime}: ${server}” | Out-File $log -Append
    } else {
        Write-output “AutomationServices is not running: ${Logtime}: ${server}” | Out-File $log -Append
    }
}
VS running as admin?

A: domain user account
I'll make one last attempt before bowing out since I'm not familiar with the ServiceController class:  Call PowerShell from c#?

https://docs.microsoft.com/en-us/powershell/scripting/developer/hosting/adding-and-invoking-commands?view=powershell-6
As @Shaun Vermaak alluded to, the user requesting access to the services controller must have permissions to use it and everything else in the chain that is required to reach that service within that domain. This is why running the script as a Domain Administrator (or at least a user that is in the Administrators group on that machine) would likely work.
but i'm running the script to check service of a remote server from VS.
and i see System.ServiceProcess.dll under C:\Windows\Microsoft.NET\Framework\v2.0.50727

i learned that to use ServiceController, you need to add reference to System.ServiceProcess;
but when i add
using System.ServiceProcess;

it says ServiceProcess is a type not a namespace.
and I had not problem checking the remote server's service status using PowerShell
Since PowerShell works and nothing else you have attempted has, did you try calling PowerShell from inside c#?
I thought about wrapping PowerShell inside c# but I just want to make the simple c# code work, and also i'm not sure if they allow putting PowerShell inside c# since they do not allow PowerShell.

well, i made it work, by adding namespace ServiceProcess to ServiceControllerStatus Enum.

ServiceController sc = new ServiceController();
            sc.ServiceName = "AutomationServices";
            sc.MachineName = "APP01.company.com";


            if (sc.Status == ServiceProcess.ServiceControllerStatus.Running)
                // MessageBox.Show("The service is running.");
                Dts.Variables["User::ServiceStatus"].Value = "Running";


Thanks all for contributing your ideas!
full code:
----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
using System;
using System.Data;
using Microsoft.SqlServer.Dts.Runtime;
using System.Windows.Forms;

namespace ST_cef55417ebae4195b01d26ad7bea39b4
{

	[Microsoft.SqlServer.Dts.Tasks.ScriptTask.SSISScriptTaskEntryPointAttribute]
    public partial class ScriptMain : Microsoft.SqlServer.Dts.Tasks.ScriptTask.VSTARTScriptObjectModelBase
    {
        public void Main()
		{
            ServiceController sc = new ServiceController();
            sc.ServiceName = "AutomationServices";
            sc.MachineName = "APP01.company.com";


            if (sc.Status == ServiceProcess.ServiceControllerStatus.Running)
            // MessageBox.Show("The service is running.");
            {
                Dts.Variables["User::ServiceStatus"].Value = "Running";
            }

            Dts.TaskResult = (int)ScriptResults.Success;
		}

        enum ScriptResults
        {
            Success = Microsoft.SqlServer.Dts.Runtime.DTSExecResult.Success,
            Failure = Microsoft.SqlServer.Dts.Runtime.DTSExecResult.Failure
        };

        private class ServiceController
        {
            public string MachineName { get; internal set; }
            public string ServiceName { get; internal set; }
            public object Status { get; internal set; }
        }

    }
}

Open in new window

VS running as admin?

A: domain user account

you may try to add an icon for VS to your desktop (if not already exists) and edit properties of the icon to run VS 'as administrator'.

Sara
This question needs an answer!
Become an EE member today
7 DAY FREE TRIAL
Members can start a 7-Day Free trial then enjoy unlimited access to the platform.
View membership options
or
Learn why we charge membership fees
We get it - no one likes a content blocker. Take one extra minute and find out why we block content.