How to get applications associated with a application pool in IIS7 - c#

I have a virtual directory name. For this virtual directory i have to find out the application pool associated. Once i get the application pool i have to find out all the virtual directories on this application pool..
I am using this code to find out the application pool associated with virtual
directory
string AppPoolName = string.Empty;
ServerManager manager = new ServerManager();
foreach (Site site in manager.Sites)
{
foreach (Application app in site.Applications)
{
string path = app.Path;
path = path.Replace("/", " ");
path = path.Trim();
if (path.ToLower() == VDName.ToLower())
{
AppPoolName = app.ApplicationPoolName;
break;
}
}
}

using (var serverManager = new ServerManager())
{
var apps = (from site in serverManager.Sites
from app in site.Applications
where app.ApplicationPoolName.Equals("DefaultAppPool")
select app);
}

I think we have to rerun the function for application pool to get the name for applications associated.
ServerManager manager = new ServerManager();
foreach (Site site in manager.Sites)
{
foreach (Application app in site.Applications)
{
if (app.ApplicationPoolName.ToString() == AppPoolName)
{
string appname = app.Path;
}
}
}

Or a new line no looping approach:
Environment.GetEnvironmentVariable("APP_POOL_ID", EnvironmentVariableTarget.Process);

Related

How to create a subfolder in a subsubfolder SharePoint Online C#

I want to create some folders in the document library in C#.
The folder structure should be as follows in the document library:
"98_Projekte" --> "Muster Mandant" --> "01 Test Subfolder"
In my C# code, I only create the sub folder "Muster Mandant" in "98_Projekte". That is correct, but I want afterwards to create new subfolders in "Muster Mandant" (see second foreach).
public static void AddFolder(ClientContext context, string[] folders)
{
Web web = context.Web;
var docLibrary = web.DefaultDocumentLibrary().RootFolder;
context.Load(docLibrary);
context.ExecuteQuery();
foreach (Microsoft.SharePoint.Client.Folder subFolder in docLibrary.Folders)
{
if (subFolder.Name == "98_Projekte")
{
subFolder.Folders.Add("Muster Mandant");
context.ExecuteQuery();
docLibrary = subFolder;
docLibrary.Update();
}
}
foreach (Microsoft.SharePoint.Client.Folder subSubFolder in docLibrary.Folders)
{
if (subSubFolder.Name == "Muster Mandant")
{
foreach (string folder in folders)
{
subSubFolder.Folders.Add(folder);
}
}
}
context.ExecuteQuery();
}
}
Do you have any solutions?
You may check below code.
public static Folder AddSubFolder(ClientContext context, Folder ParentFolder, string folderName)
{
Folder resultFolder=ParentFolder.Folders.Add(folderName);
context.ExecuteQuery();
return resultFolder;
}
static void Main(string[] args)
{
using (var context = new ClientContext("https://domain.sharepoint.com/sites/TST/"))
{
string password = "pw";
SecureString sec_pass = new SecureString();
Array.ForEach(password.ToArray(), sec_pass.AppendChar);
sec_pass.MakeReadOnly();
context.Credentials = new SharePointOnlineCredentials("lee#domain.onmicrosoft.com", sec_pass);
Web web = context.Web;
var folders = web.DefaultDocumentLibrary().RootFolder.Folders;
context.Load(folders);
context.ExecuteQuery();
foreach (Folder subFolder in folders)
{
if (subFolder.Name == "98_Projekte")
{
Folder parent1= AddSubFolder(context,subFolder,"Muster Mandant");
AddSubFolder(context, parent1, "01 Test Subfolder");
}
}
Console.WriteLine("Done");
Console.ReadKey();
}
}
I think the problem is that your code is expecting the .Folders property to contain all folders (recursive) and instead you are just getting the direct children of the root folder. In your 2nd loop check the context of the docLibrary.Folders property/collection and see what is returned.

C# Get service log on as using ServiceController class?

Is it possible to get the logon as account using the ServiceController class? I am using the following code to get the service display names and the service status on a remote machine. I do not see a property indicating what account the service is running under. If not then is there another class that I can use to find out what account a service is running under?
ServiceController[] services = ServiceController.GetServices("MyRemotePC");
foreach (ServiceController service in services)
{
Console.WriteLine(
"The {0} service is currently {1}.",
service.DisplayName,
service. Status
);
}
For each service the following first checks to see if the service is running.
If so, it gets the service's processId and uses ManagementObjectSearch to retrieve the corresponding process object. From there it calls GetOwner(out string user, out string domain) from the underlying Win32_Process object, and outputs the result if the call was successful.
The code below worked locally, however I don't have the access to test this against a remote computer. Even locally I had to run the application as an administrator. for GetOwner to not return an error result of 2 (Access Denied).
var services = ServiceController.GetServices("MyRemotePC");
var getOptions = new ObjectGetOptions(null, TimeSpan.MaxValue, true);
var scope = new ManagementScope(#"\\MyRemotePC\root\cimv2");
foreach (ServiceController service in services)
{
Console.WriteLine($"The {service.DisplayName} service is currently {service.Status}.");
if (service.Status != ServiceControllerStatus.Stopped)
{
var svcObj = new ManagementObject(scope, new ManagementPath($"Win32_Service.Name='{service.ServiceName}'"), getOptions);
var processId = (uint)svcObj["ProcessID"];
var searcher = new ManagementObjectSearcher(scope, new SelectQuery($"SELECT * FROM Win32_Process WHERE ProcessID = '{processId}'"));
var processObj = searcher.Get().Cast<ManagementObject>().First();
var props = processObj.Properties.Cast<PropertyData>().ToDictionary(x => x.Name, x => x.Value);
string[] outArgs = new string[] { string.Empty, string.Empty };
var returnVal = (UInt32)processObj.InvokeMethod("GetOwner", outArgs);
if (returnVal == 0)
{
var userName = outArgs[1] + "\\" + outArgs[0];
Console.WriteLine(userName);
}
}
}

Assign App pool to site in IIS6 using c#

I am trying to create and assign application pool to a website in IIS6 and IIS7 using c#. I managed to do this for IIS7 using Microsoft.Web.Administration; but since its not supported in IIS6 i want to accomplish this using System.DirectoryServices;. I have managed to create the application pool but the assigning application pool does not work.
Here is what I have so far...
private static string DefaultAppPool = "DefaultAppPool";
public static void SetApplicationPoolIIS6(string websiteName)
{
string metabasePath = "IIS://localhost/W3SVC";
string appPoolName = GetSavedApplicationPoolName(websiteName);
if (string.IsNullOrEmpty(appPoolName) || appPoolName.Equals(DefaultAppPool))
appPoolName = websiteName + "AppPool";
bool isAppPoolCreated = IsAppPoolCreatedIIS6(websiteName, appPoolName);
if (!isAppPoolCreated)
CreateApplicationPoolIIS6(appPoolName, metabasePath);
DirectoryEntry w3svc = new DirectoryEntry(metabasePath);
w3svc.RefreshCache();
foreach (DirectoryEntry item in w3svc.Children)
{
string siteName = item.Properties["ServerComment"].Value == null ? "" : item.Properties["ServerComment"].Value.ToString();
if (string.IsNullOrEmpty(siteName))
continue;
if (siteName.Equals(websiteName))
{
item.Invoke("Stop", null);
item.Properties["AppPoolId"].Value = appPoolName;
item.CommitChanges();
item.Invoke("Start", null);
break;
}
}
w3svc.CommitChanges();
DirectoryEntry w3svc2 = new DirectoryEntry(metabasePath);
w3svc2.RefreshCache();
SaveWebSiteSettingsIIS6(websiteName, appPoolName);
}
Any idea why the below lines don't assign the created app pool ?
item.Properties["AppPoolId"].Value = appPoolName;
item.CommitChanges();
Any help is much appreciated. Thank you.

Azure Resource Manager REST API Create virtual directory

I am creating virtual directory in a virtual application using Azure Resource Manager REST API with HttpClient. After authentication I am doing a PUT request. Below is the code.
client.PutAsJsonAsync(requestUri,
new
{
properties =
new
{
virtualApplications = new
{
virtualPath = "/",
physicalPath = "site\\wwwroot",
preloadEnabled = false,
virtualDirectories = new
{
virtualPath = "/Abdul",
physicalPath = "site\\Abdul"
}
}
}
}).Wait();
The code is executed successfully. But virtual directory is not created. Am I using the right format?

Programatically create an IIS website on button click [duplicate]

We have been able to create a web site. We did this using the information in this link:
https://msdn.microsoft.com/en-us/library/ms525598.aspx
However, we would like to use a port number other that port 80. How do we do this?
We are using IIS 6
If you're using IIS 7, there is a new managed API called Microsoft.Web.Administration
An example from the above blog post:
ServerManager iisManager = new ServerManager();
iisManager.Sites.Add("NewSite", "http", "*:8080:", "d:\\MySite");
iisManager.CommitChanges();
If you're using IIS 6 and want to do this, it's more complex unfortunately.
You will have to create a web service on every server, a web service that handles the creation of a website because direct user impersonation over the network won't work properly (If I recall this correctly).
You will have to use Interop Services and do something similar to this (This example uses two objects, server and site, which are instances of custom classes that store a server's and site's configuration):
string metabasePath = "IIS://" + server.ComputerName + "/W3SVC";
DirectoryEntry w3svc = new DirectoryEntry(metabasePath, server.Username, server.Password);
string serverBindings = ":80:" + site.HostName;
string homeDirectory = server.WWWRootPath + "\\" + site.FolderName;
object[] newSite = new object[] { site.Name, new object[] { serverBindings }, homeDirectory };
object websiteId = (object)w3svc.Invoke("CreateNewSite", newSite);
// Returns the Website ID from the Metabase
int id = (int)websiteId;
See more here
Heres the solution.
Blog article : How to add new website in IIS 7
On Button click :
try
{
ServerManager serverMgr = new ServerManager();
string strWebsitename = txtwebsitename.Text; // abc
string strApplicationPool = "DefaultAppPool"; // set your deafultpool :4.0 in IIS
string strhostname = txthostname.Text; //abc.com
string stripaddress = txtipaddress.Text;// ip address
string bindinginfo = stripaddress + ":80:" + strhostname;
//check if website name already exists in IIS
Boolean bWebsite = IsWebsiteExists(strWebsitename);
if (!bWebsite)
{
Site mySite = serverMgr.Sites.Add(strWebsitename.ToString(), "http", bindinginfo, "C:\\inetpub\\wwwroot\\yourWebsite");
mySite.ApplicationDefaults.ApplicationPoolName = strApplicationPool;
mySite.TraceFailedRequestsLogging.Enabled = true;
mySite.TraceFailedRequestsLogging.Directory = "C:\\inetpub\\customfolder\\site";
serverMgr.CommitChanges();
lblmsg.Text = "New website " + strWebsitename + " added sucessfully";
}
else
{
lblmsg.Text = "Name should be unique, " + strWebsitename + " is already exists. ";
}
}
catch (Exception ae)
{
Response.Redirect(ae.Message);
}
Looping over sites whether name already exists
public bool IsWebsiteExists(string strWebsitename)
{
Boolean flagset = false;
SiteCollection sitecollection = serverMgr.Sites;
foreach (Site site in sitecollection)
{
if (site.Name == strWebsitename.ToString())
{
flagset = true;
break;
}
else
{
flagset = false;
}
}
return flagset;
}
Try the following Code to Know the unUsed PortNo
DirectoryEntry root = new DirectoryEntry("IIS://localhost/W3SVC");
// Find unused ID PortNo for new web site
bool found_valid_port_no = false;
int random_port_no = 1;
do
{
bool regenerate_port_no = false;
System.Random random_generator = new Random();
random_port_no = random_generator.Next(9000,15000);
foreach (DirectoryEntry e in root.Children)
{
if (e.SchemaClassName == "IIsWebServer")
{
int site_id = Convert.ToInt32(e.Name);
//For each detected ID find the port Number
DirectoryEntry vRoot = new DirectoryEntry("IIS://localhost/W3SVC/" + site_id);
PropertyValueCollection pvcServerBindings = vRoot.Properties["serverbindings"];
String bindings = pvcServerBindings.Value.ToString().Replace(":", "");
int port_no = Convert.ToInt32(bindings);
if (port_no == random_port_no)
{
regenerate_port_no = true;
break;
}
}
}
found_valid_port_no = !regenerate_port_no;
} while (!found_valid_port_no);
int newportId = random_port_no;
I have gone though all answer here and also tested. Here is the most clean smarter version of answer for this question. However this still cant work on IIS 6.0. so IIS 8.0 or above is required.
string domainName = "";
string appPoolName = "";
string webFiles = "C:\\Users\\John\\Desktop\\New Folder";
if (IsWebsiteExists(domainName) == false)
{
ServerManager iisManager = new ServerManager();
iisManager.Sites.Add(domainName, "http", "*:8080:", webFiles);
iisManager.ApplicationDefaults.ApplicationPoolName = appPoolName;
iisManager.CommitChanges();
}
else
{
Console.WriteLine("Name Exists already");
}
public static bool IsWebsiteExists(string strWebsitename)
{
ServerManager serverMgr = new ServerManager();
Boolean flagset = false;
SiteCollection sitecollection = serverMgr.Sites;
flagset = sitecollection.Any(x => x.Name == strWebsitename);
return flagset;
}
This simplified method will create a site with default binding settings, and also create the application pool if needed:
public void addIISApplication(string siteName, string physicalPath, int port, string appPoolName)
{
using (var serverMgr = new ServerManager())
{
var sitecollection = serverMgr.Sites;
if (!sitecollection.Any(x => x.Name.ToLower() == siteName.ToLower()))
{
var appPools = serverMgr.ApplicationPools;
if (!appPools.Any(x => x.Name.ToLower() == appPoolName.ToLower()))
{
serverMgr.ApplicationPools.Add(appPoolName);
}
var mySite = serverMgr.Sites.Add(siteName, physicalPath, port);
mySite.ApplicationDefaults.ApplicationPoolName = appPoolName;
serverMgr.CommitChanges();
}
}
}
In properties of site select "Web Site" tab and specify TCP Port.
In studio to debug purpose specify http://localhost:<port>/<site> at tab Web for "Use Local IIS Web Server"

Categories