Check if an Azure VM is running - c#

I want to query an existing azure virtual machine to check whether it is fully deployed and able to be connected to remotely. Is there any way to do this using the Azure Rest API?
I've outlined my current process and why I desire such a call below.
I am using the Windows Azure management library to create a VM using ComputeManagementClient and the CreateDeploymentAsync function. This then returns a status of Succeeded, if I then do a get on the deployment it has a status of DeploymentStatus.Running.
After this has run I am trying to create a remote powershell connection so I can format the disk. I keep getting an error on this as it is unable to create the session.
WinRM cannot complete the operation. Verify that the specified computer name is valid, that the computer is accessible over the network, and that a firewall exception for the WinRM service is enabled and allows access from this computer. By default, the WinRM firewall exception for public profiles limits access to remote computers within the same local subnet. For more information, see the about_Remote_Troubleshooting Help topic.
If I go to the azure management portal the status is provisioning, I assume this is why i cannot create a session.
Process
CreateAzureVM()
CheckAzureVmCanBeConnectedTo() //I am unable to do this correctly
RunPowershellScriptOnVM() // this fails

You should be able to use Get Deployment to poll for the role's InstanceStatus (note that InstanceStatus != Status). When the InstanceStatus is ReadyRole, you should be able to log into your machine.
There's a distinction between a Deployment status and a Role InstanceStatus. Think of the role as an actual virtual machine, whereas a Deployment may describe multiple VMs.

SubscriptionCloudCredentials certificate = new CertificateCloudCredentials(subscriptionId, x509Certificate);
IComputeManagementClient ComputeManagementClient = new ComputeManagementClient(certificate);
var deployments = ComputeManagementClient.Deployments.GetBySlot(hostedServiceName, DeploymentSlot.YourDeploymentSlot);
var state = deployments.RoleInstances.First().PowerState;
I hope that this will help you.

Without seeing your code it's hard to say exactly what you need to do but I would recommend that you utilise the await keyword to wait for the completion of the call to the Azure API to create the VM. See the code samples under "Deploy a Virtual Machine" in this MSDN guide: http://msdn.microsoft.com/en-us/library/azure/dn722415.aspx#bk_createres

Related

C# The network path was not found

Im having trouble with writing files to remote directory via network. The following code fails when I try to check if the directory exists:
if (!Directory.Exists(processingPath))
Directory.CreateDirectory(processingPath);
processingPath is composed like
processingPath = xxxObject.serverPath + "processing\\";
xxxObject.serverPath contains something like this
\\machineNetworkName\sharedFolder\
Its working properly, but when many requests are processing (running as tasks asynchronously), it stops working and failing into exception:
System.IO.IOException: The network path was not found.
Could you please help me what could be the problem and why it is failing after some time on network path???
Thanks for your solutions
I got the same error before, it was about authentication problems.
You have to be sure that you set properly the user on IIS, because it use a Default App Pool's identity which can't access to your NFS.
You can also use IIS virtual folders to set the identity.
(on IIS manager, see App Pool settings -> Identity and also virtual folders settings -> identity).
In my case, it worked better by using the Impersonation directly in the code, so I recommend you to use the VladL WrappedImpersonationContext Object: How to provide user name and password when connecting to a network share
Last thing to check, the owner of the files on your NFS server, if they were created under the root user, it might not work.
I had the same problem and solved it. The problem in my code and I see it in yours, too, is that you have the slash at the end of the network path.
Instead of processingPath = xxxObject.serverPath + "processing\\"; write: processingPath = xxxObject.serverPath + "processing";

Accessing Network Path in Windows Service C#

I have developed a windows service using local system as Account. I have used
network path of file
FileInfo fi = new FileInfo(#"\\epm-server\penDocuments_LabMeds\" + Convert.ToString(dr["mrn"]) + "\\SyncedXML\\" + Convert.ToString(dr["xmlfile"]));
if (!fi.Exists)
boolFileNotFound = true;
A dynamic path of a file that is built from database.
It works fine when I run Windows Service in Debug Mode, but when I install it then fileNotExists returns TRUE always like the file doesnt exist but infact it does exist.
This is bugging me a lot now. Kindly help me why its not working. Its a server path. Its getting opened in my PC.
Thanks
Did you notice the double backslashes in front and after SyncedXML (\\SyncedXML\\)?
This is probably the cause of your error.
Additionally I'd use string.Format in such cases to reduce the inadvertently addition of unwanted characters:
var path = string.Format(#"\\epm-server\penDocuments_LabMeds\{0}\SyncedXML\{1}", dr[mrn], dr[xmlfile]);
var fi = new FileInfo(path);
Edit:
If it's permission-related, then it's very likely that your local system account (in whose context the service is running) isn't allowed to access the epm-server.
The path is accessible if you're opening it directly or if you're running the service in debug mode as this is happening in your user context (e.g. YOURDOMAIN\vickyshazad), and you're allowed to access the ressource, whereas NT AUTHORITY\SYSTEM is not.
It's usually a good practise to have a special service account for your developed windows service and grant this user only and exactly the required permissions (least privilege). Maybe ask your system administrator for a service user.
Local System (NT AUTHORITY\SYSTEM) is a highly privileged account that's not recommended to use in general (see MSDN).
Most services do not need such a high privilege level. If your service does not need these privileges, and it is not an interactive service, consider using the LocalService account or the NetworkService account.

Get service name inside service

I want to get service name inside service. The rough idea is to get process id and compare the process id with services enumerated by WMI, ServiceCotroller or EnumServicesStatusEx() API.
The problem is that the service is running under a domain account (it isn't local administrator). When I want to enumerate the services inside the running service, the running service itself is missing from enumeration!
If I move the service account to local administrator, the running service is found. So it isn't code issue. (If code issue, the behavior should be same: service not found.)
If I extract the logic to a console application (or by powershell) and run application or powershell under service account, the service is found, too. So it isn't permission issue. (If permission issue, the behavior should be same: service not found.)
The service CANNOT be enumerated when the service account IS NOT administrator and INSIDE service. It is very wire issue.
I check documentation for EnumServicesStatusEx from MSDN and find local administrator has extra SC_MANAGER_LOCK than local authenticated user. Is it the reason? But I CANNOT link the lock with service enumeration.
Or somebody please indicate a way to query service name inside the service.
Thanks.
BTW, It is on Windows 2008 R2.
I found a related question: How to get name of windows service from inside the service itself.
the 1st answer is not acceptable for me. I want to provide a common library and has no control to installer.
the 2nd answer is same idea with me. I guess it should be same with my result.
It is a permission issue.
Run psservice from Sysinternals like:
psservice.exe security InstrumentationTestService
and I got the following result:
PsService v2.24 - Service information and configuration utility
Copyright (C) 2001-2010 Mark Russinovich
Sysinternals - www.sysinternals.com
SERVICE_NAME: InstrumentationTestService
DISPLAY_NAME: InstrumentationTestService
ACCOUNT: LocalSystem
SECURITY:
[ALLOW] NT AUTHORITY\SYSTEM
Query status
Query Config
Interrogate
Enumerate Dependents
Pause/Resume
Start
Stop
User-Defined Control
Read Permissions
[ALLOW] BUILTIN\Administrators
All
[ALLOW] NT AUTHORITY\INTERACTIVE
Query status
Query Config
Interrogate
Enumerate Dependents
User-Defined Control
Read Permissions
[ALLOW] NT AUTHORITY\SERVICE
Query status
Query Config
Interrogate
Enumerate Dependents
User-Defined Control
Read Permissions
It indicates that my service account has no permission to Query the service status.
If I use service account to run powershell/WMI/ServiceController, the service account will turn into a INTERACTIVE user. So it has the permission to query service status.
The solution is to grant the service account Query status permission.
This is not a pure PowerShell answer, but you've got a good tool as far as EXEs,DLLs and SERVICEs are concerned it's TASKLIST.EXE.
Have a look to /FI and /FO. In the following sample I get information for the search service.
tasklist /FI "SERVICES eq WSearch" /FO "CSV"
To integrate it with PowerShell youcan use :
tasklist /FI "SERVICES eq WSearch" /FO "CSV" | ConvertFrom-Csv

C# Impersonation technique

I wanted to remove a config file from a remote machine having IP as : sj1slm612. Now the problem is i do not have full modification rights to that remote machine, so I'm using impersonation technique to do this. Normally when I'm connected to this remote machine via putty, I use 'sudo'. So my question is will the following code be able to solve my problem ? Thanks.
My Code :
AppDomain.CurrentDomain.SetPrincipalPolicy(System.Security.Principal.PrincipalPolicy.WindowsPrincipal);
using (WindowsIdentity Authorized_user = new WindowsIdentity("sj1slm612\\wtsnqa", "password"))
{
using (WindowsImpersonationContext context = Authorized_user.Impersonate())
{
File.Delete(#"/apps/instances/express_13000/configuration/standalone-full.xml");
File.Delete(#"/apps/instances/query_13100/configuration/standalone-full.xml");
File.Delete(#"/apps/instances/wppapi_13200/configuration/standalone-full.xml");
File.Delete(#"/apps/instances/wppgui_13300/configuration/standalone-full.xml");
Console.WriteLine("All config files removed from sj1slm612");
Console.ReadLine();
There are 2 problems with your approach:
You are trying to impersonate a remote machine account on a local machine; this won't work. The credentials of a machine account can only be validated by that machine. In addition, that account has no rights on the local machine, so it doesn't really make sense to impersonate it. You need to impersonate a domain account. When you use a tool like putty, the credentials are sent to the remote machine and not validated by the local machine. This is why you can use a machine account of the remote machine.
You need to give proper paths for the files. Nowhere do you indicate that these files are on the remote machine. Use something like "\\machine\c$\path\to\file".
The details on what are going to work or not will depend on your network and OS, which you didn't specify, though it sounds Linux-ish. There may be a different syntax for referring to remote files that you need to use.

Monitoring Windows service status remotely as non-administrator?

Background: I have an application that, among other parts of its back-end, uses a server-side Windows service to do some of the computation.
What I'm trying to do is display the status of the service (Running vs. Stopped, essentially) on the client, such that the users can know (a) if the background computation is happening, or (b) if they need to go poke their IT guy to check the server. (It's written for an SME customer that doesn't have a full-time IT department or a budget that wants to be spent on fancy service-monitoring-and-alerting software.)
In itself, that's easy enough to do with ServiceController - if you're an administrator on the server, which the users, of course, aren't. Is there a way to read service status from a remote server in .NET as a non-administrative user? (All I need is to read the status; I don't need, and actually specifically don't want, to give the users the rights to stop/restart/alter the service in any way.)
If the user under which your application works doesn't have sufficient permissions for accessing services, you're likely to get an error like this:
service.Status threw an exception of type 'System.InvalidOperationException'
Cannot open MyService service on computer '192.168.0.7'. Access is denied.
You need to switch to another user context to be able to monitor it. If you don't want to do it for entire application (which is rather obvious), try impersonation for the actual piece of code which does the status checking. What should be the user? Actually for the safety reasons, it definitely shouldn't be the user who has an access for entire machine. It should has access just for controlling the services. Ask the administrator to create such a user for you. The status monitoring can be then executed like this:
public string GetServiceStatus(string machine, string service)
{
return Impersonate(
() =>
{
var service = new ServiceController(machine, service);
service.Refresh();
return service.Status;
}, USER, DOMAIN, PASSWORD
);
}
The entire thread with detailed solution can be found here.
Edit:
Let me explain the topic further. The solution I've provided gives the opportunity to change the user context, for some particular piece of code. It can be whatever you want e.g. service status checking. User, under context such an operation is going to be executed, can have granted the access to perform it, or not. It's completely different story though. It's the computer administrator responsibility to grant such an access. In the simplest case he can just add such a user to the Administrators group, which will be reckless, but he can also grant granular access using Group Policy. More detailed information regarding such an administration issues can be found here and here.

Categories

Resources