Why the IIS application pool is not created at all? - c#

There is something terribly wrong below but i just cannot figure out what.
Although the website is created like a charm, the Application pool that should be associated with it, is not created at all.
public string Create(string sitename)
{
try
{
using (ServerManager serverMgr = new ServerManager())
{
string strhostname = sitename + "." + domain;
string bindinginfo = ":80:" + strhostname;
if (!IsWebsiteExists(serverMgr.Sites, strhostname))
{
Site mySite = serverMgr.Sites.Add(strhostname, "http", bindinginfo, "C:\\admin\\" + domain);
ApplicationPool newPool = serverMgr.ApplicationPools.Add(strhostname);
newPool.ManagedRuntimeVersion = "v4.0";
newPool.ManagedPipelineMode = ManagedPipelineMode.Integrated;
serverMgr.CommitChanges();
return "Website " + strhostname + " added sucessfully";
}
else
{
return "Name should be unique, " + strhostname + " already exists.";
}
}
}
catch (Exception ex)
{
return ex.Message;
}
}
What am i doing wrong here?

What's happening here is that when you create your site it automatically gets assigned to the DefaultAppPool.
What you need to do is replace your site's root Application (/) and point it at the application pool you just created.
The easiest way to do this is to first clear your new site's Application collection, then add a new root application that points to your application pool.
Taking your code snippet I changed it to the following:
Site mySite = serverMgr.Sites.Add(strhostname, "http", bindinginfo, "C:\\admin\\" + domain);
// Clear Applications collection
mySite.Applications.Clear();
ApplicationPool newPool = serverMgr.ApplicationPools.Add(strhostname);
newPool.ManagedRuntimeVersion = "v4.0";
newPool.ManagedPipelineMode = ManagedPipelineMode.Integrated;
// Create new root app and specify new application pool
Application app = mySite.Applications.Add("/", "C:\\admin\\" + domain);
app.ApplicationPoolName = strhostname;
serverMgr.CommitChanges();

I wouldnt expect the App Pool name to have punctuation in it. Adding the domain as part of the app pool name is a little unusual - perhaps thats the source. The basic method is discussed here, along with the appcmd syntax to make the same thing happen on the command line - try creating your app pool on the cmd line to see if your parameters are acceptable.
Create an application pool that uses .NET 4.0

Related

How to configure firwall to allow RPC

I am trying to change IIS App Pool Identity (user) remotely using C# and getting an error
System.Runtime.InteropServices.COMException (0x800706BA): The RPC server is unavailable.
I am able to do it properly if I allow all RPC dynamic port (in the range of 49152 to 65535) from firewall for all services on a remote machine.
I just want to know the exact service or process name used by the remote system to complete the process so that I can allow the ports for that service only.
public static bool ChangeAppPoolUser(string ip, string machineName, string username, string password, string applicationPoolName)
{
try
{
var metabasePath = "IIS://" + ip + "/W3SVC/AppPools";
// Get list of appPools at specified metabasePath location
using (DirectoryEntry appPools = new DirectoryEntry(metabasePath, username, password))
{
if(appPools==null)
{
Helper.PrepareDebugLog("appPools is null");
}
Helper.PrepareDebugLog("metabasePath:" + metabasePath + " username:" + username + " password:" + password);
// From the list of appPools, Search and get the appPool
using (DirectoryEntry AppPool = appPools.Children.Find(applicationPoolName, "IIsApplicationPool"))
{
Helper.PrepareDebugLog("in");
if (AppPool != null)
{
AppPool.InvokeSet("AppPoolIdentityType", new Object[] { 3 });
// Configure username for the AppPool with above specified username
AppPool.InvokeSet("WAMUserName", new Object[] { Environment.UserDomainName + "\\" + Environment.UserName });
// Configure password for the AppPool with above specified password
AppPool.InvokeSet("WAMUserPass", new Object[] { CommonProgramVariables.localPassword });
// Write above settings to IIS metabase
AppPool.Invoke("SetInfo", null);
// Commit the above configuration changes that are written to metabase
AppPool.CommitChanges();
return true;
}
}
}
}
catch (Exception e)
{
Helper.PrepareLogWithTimstamp("EXCEPTION WHILE CHNAGE USER: Parameter USED machineName:" + machineName + " username:" + username + " password:" + password + " applicationPoolName:" + applicationPoolName + " LocalPassword:" + CommonProgramVariables.localPassword + " Local User:" + Environment.UserDomainName + "\\" + Environment.UserName);
Helper.PrepareLog("EXCEPTION:", e);
}
return false;
}
Expected: AppPool User should be changed for remote machine AppPool.
Actual result:
System.Runtime.InteropServices.COMException (0x800706BA): The RPC server is unavailable.
The error The RPC server is unavailable. (Exception from HRESULT: 0x800706BA) can occur if RPC / WMI connections are blocked on the target machine due to Firewall restrictions or you entered incorrect hostname / IP address of the target machine.
To resolve this error you could follow the below steps:
1)Open Control Panel, click Security and then click Windows Firewall.
2)Click Change Settings and then click the Exceptions tab.
3)In the Exceptions window, select the check box for Windows Management Instrumentation (WMI) to enable WMI traffic through the firewall.

WPF: unable to map network drive for all users

I'm trying to create a function for an application to automatically copy over specific files during the final stage of a job. The only issue here is that the copy location is a protected share drive and uses a separate login instead of being validated by the active directory so I've got to do a bit of a workaround to get File.Copy() working. My workaround has been to call the built in net.exe utility and passing a command line argument that points to the share drive to open up a connection to the drive then using File.Copy() to get the file where it needs to go then deleting the connection. The issue at hand is that this works great on my computer but when anyone else on the team runs the same program a "Logon failure: unknown user name or bad password" is thrown. I'm at a bit of loss as to why this would happen since the username and password are static and not being changed and everyone on the team has the same network permissions I do. Here is the WPF/C# code I'm using to do this:
try
{
string mrdfDropPath = #"dropPathHere";
string MRDFPath = #"storePath\test.xml";
string command = #"use " + mrdfDropPath + #" /user:CORP\Username Password";
Process.Start("net.exe", command);
File.Copy(MRDFPath, mrdfDropPath + "test.xml");
string command2 = #"use " + mrdfDropPath + #" /delete";
Process.Start("net.exe", command2);
StreamWriter writer = new StreamWriter(#"logPath\log.txt", true);
writer.WriteLine(mrdfDropPath + "test.xml" + "," + File.GetLastWriteTime(MRDFPath).ToString());
writer.Close();
}
catch (Exception e)
{
StreamWriter writer = new StreamWriter(#"logPath\log.txt", true);
writer.WriteLine(e.Message);
writer.Close();
}
Like I said this works as expected during debug and when I run the application, but for anyone else it is throwing the error.

C# IIS 7.5 class not registered exception

We just started up a new webserver and i'm running into "class not registered" when creating a new application pool. I'm using the code below but I have no idea how to distinguish what is not registered. Any thoughts would be awesome.
Thanks.
string path = "IIS://" + server + "/W3SVC";
string app_pools_path = path + "/AppPools";
/error below.
var app_pools = new DirectoryEntry(app_pools_path);
foreach (DirectoryEntry app_pool in app_pools.Children)
{
//do work
}
Error "Class no registered" error code:2147221164
ON the server open the server manager
add new features ==> Web Server (IIS) ==> Management Tools ==> IIS 6 Management Compatibility then check IIS6 Metabase Compatibility. use your original connection string / path
string path = "IIS://" + server + "/W3SVC";
string app_pools_path = path + "/AppPools";
try this please :
private void StopAppPool(string app_Pool , string server)
{
try
{
ConnectionOptions co = new ConnectionOptions();
co.Username = "DomainName\\UserName";
co.Password = "UserPassword";
string appPool = "W3SVC/AppPools/" + app_Pool;
co.Impersonation = ImpersonationLevel.Impersonate;
co.Authentication = AuthenticationLevel.PacketPrivacy;
string objPath = "IISApplicationPool.Name='" + appPool + "'";
ManagementScope scope = new ManagementScope(#"\\" + server + #"\root\MicrosoftIISv2", co);
using (ManagementObject mc = new ManagementObject(objPath))
{
mc.Scope = scope;
mc.InvokeMethod("Stop", null, null);
}
}
catch (Exception e)
{
Console.WriteLine(e.Message);
Console.WriteLine(e.StackTrace);
Console.WriteLine(e.InnerException);
Console.WriteLine(e.Data);
}
//Console.ReadLine();
}
You should avoid using DirectoryEntry to manipulate IIS 7 and above. That's the old API based on IIS ADSI interfaces,
http://msdn.microsoft.com/en-us/library/ms524896(v=vs.90).aspx
IIS 6 Compatibilities might help you out though,
http://blogs.msdn.com/b/narahari/archive/2009/05/13/when-using-directoryservices-to-access-iis-schema-iis6-management-compatibility-pack-needs-to-be-installed-system-runtime-interopservices-comexception-0x80005000.aspx
The best solution (which is also strong typed and more convenient for C# developers) is Microsoft.Web.Administration,
http://www.iis.net/learn/manage/scripting/how-to-use-microsoftwebadministration

Remotely change computer name for a Windows Server 2008 machine using C#?

Might someone be able to point me towards a conclusive resource to learn how to remotely change a computer name on a Windows Server 2008 machine using C#
I've looked at lots of sites for help and now in day two of my task and not really any closer (other than deciding WMI is pretty much my only option) Totally out of my normal skillset so I guess pretty much any info would be nice, but especially anything having to do with changing a computer name remotely. (this would occur right after I remotely spin up a virutal from an image...and yes, i realize a reboot will be required)
thanks
Here is a nice link that discusses it in detail and also deals with active directory membership and machine naming in addition to the local machine name.
http://derricksweng.blogspot.com/2009/04/programmatically-renaming-computer.html
(Btw, should you have to deal with Active Directory naming, I would consider using the ComputerPrincipal class from the System.DirectoryServices.AccountManagement namespace vice anything from System.DirectoryServices namespace that was used in the blog post.)
Tweaked code from the blog post (you will need to add a reference to System.Management to your project):
public void RenameRemotePC(String oldName, String newName, String domain, NetworkCredential accountWithPermissions)
{
var remoteControlObject = new ManagementPath
{
ClassName = "Win32_ComputerSystem",
Server = oldName,
Path =
oldName + "\\root\\cimv2:Win32_ComputerSystem.Name='" + oldName + "'",
NamespacePath = "\\\\" + oldName + "\\root\\cimv2"
};
var conn = new ConnectionOptions
{
Authentication = AuthenticationLevel.PacketPrivacy,
Username = oldName + "\\" + accountWithPermissions.UserName,
Password = accountWithPermissions.Password
};
var remoteScope = new ManagementScope(remoteControlObject, conn);
var remoteSystem = new ManagementObject(remoteScope, remoteControlObject, null);
ManagementBaseObject newRemoteSystemName = remoteSystem.GetMethodParameters("Rename");
var methodOptions = new InvokeMethodOptions();
newRemoteSystemName.SetPropertyValue("Name", newName);
newRemoteSystemName.SetPropertyValue("UserName", accountWithPermissions.UserName);
newRemoteSystemName.SetPropertyValue("Password", accountWithPermissions.Password);
methodOptions.Timeout = new TimeSpan(0, 10, 0);
ManagementBaseObject outParams = remoteSystem.InvokeMethod("Rename", newRemoteSystemName, null);
}

Trying to run psexec to remote to server and recycle app pool

If I run this from my command prompt it works fine.
psexec \ServerName cscript.exe iisapp.vbs /a AppName /r
I'm trying to do the same thing with C# console app. I'm using the below code but most of the time the application hangs and doesn't complete, and the few times it does it throws an error code. Am I doing this wrong? Does anyone know where I can look up the error or error code?
static void RecycleAppPool(string sServer)
{
Console.Clear();
ProcessStartInfo p = new ProcessStartInfo("psexec.exe", "\\\\" + sServer + " cscript.exe iisapp.vbs /a <AppName> /r");
p.RedirectStandardInput = true;
p.UseShellExecute = false;
Process.Start(p);
}
When it completes with an error, looks like this
"cscript.exe exited with error code -2147024664"
EDIT
Below code working well
static void RecycleAppPool(string sServer)
{
Console.Clear();
ProcessStartInfo p = new ProcessStartInfo("psexec.exe");
p.Arguments = #"\\" + sServer + #" cscript.exe iisapp.vbs /a AppName /r";
p.UseShellExecute = false;
Process.Start(p);
}
VS2003/8/10: Tools->Error Lookup. Paste in the error code in hex. 800700E8. It's "The pipe is being closed." Not very helpful - some issue with redirection i guess.
Do you really have in the ProcessStartInfo parameter, or is that being used to replace what your actual app name is?
Have you tried recycling using appcmd instead of iisapp.vbs?
And, in this thread they recycled a remote application pool using WMI.
If it's IIS7 then you can you the web admin namespace from C#:
using System;
using System.Xml.Serialization;
using Microsoft.Web.Administration;
using System.Linq;
using System.Runtime.InteropServices;
///...
var serverManager = ServerManager.OpenRemote(#"\\myiisserver");
var appPool = serverManager.ApplicationPools["my app pool name"];
appPool.Recycle();
You can learn more about the Web Admin Namespace here. So far it has worked very well for us. BUT must be installed on the client and remote machines.
I struggled with this a lot for the last 2 days trying every solution I found online. I'm trying to recycle an application pool on remote machines on a different domain. The first method I tried with PsExec returned error 3. I tried DirectoryEntry and failed on permissions as well and then tried using ServerManager but the same issue.
Finally, I moved to WMI and it worked:
public static void RecycleIis4(string user, string password, string serverName = "LOCALHOST", string appPoolName = "DefaultAppPool")
{
var processToRun = new[] { #"c:\Windows\system32\inetsrv\appcmd recycle APPPOOL " + appPoolName };
var connection = new ConnectionOptions { Username = user, Password = password };
var wmiScope = new ManagementScope(string.Format(#"\\{0}\root\cimv2", serverName), connection);
var wmiProcess = new ManagementClass(wmiScope, new ManagementPath("Win32_Process"), new ObjectGetOptions());
wmiProcess.InvokeMethod("Create", processToRun);
}
Hope this helps.

Categories

Resources