WMI Remote connection - wmi

I have an issue regarding WMI connection through asp.net from Computer A (windows 2003 server) to Computer B (Windows XP)..
The error is as follows:
RPC server is unavailable..

There are a few steps that you must take in order to successfully leverage WMI connectivity. The basics are you must allow remote management on the target box of course. If you can’t RDP into it, chances are, you can’t remote manage anything else. This can also include Windows firewall issues too. Make sure your request can even get in at all.
Next, start simple. Can you even poll for the running processes on that box? Try to output all the running processes on the target box with System.Diagnostics.Process currentProcess = System.Diagnostics.Process.GetProcesses("machine-name"). If you can at least get some information on the box then the RPC message you are getting has to do with incorrect arguments being passed in, perhaps?
Anyways, I recently wrote a web application that allowed the users to find a server on the LAN and kill a target process there or start a new one. I did it in C# so the code snippet below is just what I used. It's not the best but its working in production right now:
public static class RemoteProcessAccess
{
public static void KillProcessByProcessID(string NameOfServer, string DomainName, string LogIn, string Password, int processID)
{
//#1 The vars for this static method
#region /// <variables> ...
string userName;
string password;
string machineName;
string myDomain;
Hashtable hs = new Hashtable();
ManagementScope mScope;
ConnectionOptions cnOptions;
ManagementObjectSearcher objSearcher;
ManagementOperationObserver opsObserver;
ManagementClass manageClass;
DirectoryEntry entry;
DirectorySearcher searcher;
DirectorySearcher userSearcher;
#endregion
//#2 Set the basics sent into the method
machineName = NameOfServer;
myDomain = DomainName;
userName = LogIn;
password = Password;
cnOptions = new ConnectionOptions();
cnOptions.Impersonation = ImpersonationLevel.Impersonate;
cnOptions.EnablePrivileges = true;
cnOptions.Username = myDomain + "\\" + userName;
cnOptions.Password = password;
mScope = new ManagementScope(#"\\" + machineName + #"\ROOT\CIMV2", cnOptions);
//#3 Begin Connection to Remote Box
mScope.Connect();
objSearcher = new ManagementObjectSearcher(String.Format("Select * from Win32_Process Where ProcessID = {0}", processID));
opsObserver = new ManagementOperationObserver();
objSearcher.Scope = mScope;
string[] sep = { "\n", "\t" };
//#4 Loop through
foreach (ManagementObject obj in objSearcher.Get())
{
string caption = obj.GetText(TextFormat.Mof);
string[] split = caption.Split(sep, StringSplitOptions.RemoveEmptyEntries);
// Iterate through the splitter
for (int i = 0; i < split.Length; i++)
{
if (split[i].Split('=').Length > 1)
{
string[] procDetails = split[i].Split('=');
procDetails[1] = procDetails[1].Replace(#"""", "");
procDetails[1] = procDetails[1].Replace(';', ' ');
switch (procDetails[0].Trim().ToLower())
{
//You could look for any of the properties here and do something else,
case "processid":
int tmpProc = Convert.ToInt32(procDetails[1].ToString());
//if the process id equals the one passed in....
//(this is redundant since we should have limited the return
//by the query where above, but we're paranoid here
if (tmpProc.Equals(processID))
{
obj.InvokeMethod(opsObserver, "Terminate", null);
}
break;
}//end process ID switch...
}//end our if statement...
}//end our for loop...
}//end our for each loop...
}//end static method
}

Look at KB875605 ("How to troubleshoot WMI-related issues in Windows XP SP2")

You could enable the RPC server on any target machine by running this on the target's command prompt:
[/code]
netsh firewall set service RemoteAdmin
[/code]
Worked for me at least. :)

Try to use wmic command line to get information from the remote computer, also you can install the code of Services+ and try to connect and debug your connection to the server, most likely it is firewall problem or RPC services is down or disabled.

Related

Call a python code from WCF

I need to make a python code available as WCF for another application to access it. The python code was build by the data science team and have no ability to change it. I tried running the program as a process shell but it gives 'System.InvalidOperationException' exception.
I created the same program as C# console application and it works fine. The question is
a. Is this the right way to go about making python code available to another application (REST API is not an option).
b. What is the issue with my code.
public string ClassifyText(string value)
{
string textoutput = "";
string exeFileName = HttpContext.Current.Server.MapPath("~/python.exe");
string argName = HttpContext.Current.Server.MapPath("~/predictionscript.py");
ProcessStartInfo start = new ProcessStartInfo();
start.FileName = exeFileName;
start.Arguments = argName;
start.UseShellExecute = false;
start.RedirectStandardOutput = true;
using (Process process = Process.Start(start))
{
using (StreamReader reader = process.StandardOutput)
{
string result = reader.ReadToEnd();
textoutput = result;
}
}
return textoutput;
}

Creating Internal Accounts in SAS Metadata Server by programm on SAS Base

I'm trying to create Internal Accounts programmaticaly by using proc metadata.
The code section below creates person with External Login.
put"<Person Name=%str(%')&&PersonName&i.%str(%')>";
put"<Logins>";
put"<Login Name=%str(%')Login.&&PersonName&i.%str(%') Password=%str(%')&&word&i.%str(%')/>";
put"</Logins>";
put"</Person>";
To create ExternalLogin we can set attribute Password, and in SAS Metadata it will be encrypted automaticaly.
But to create InternalLogin type of object it is necessary to make the hash value of the password and the salt. I know that the standard sas002 encryption method, but in the case of using proc pwencode how to obtain the value of salt?
Is it possible create InternalLogin by using SAS Base?
Thanx.
So on. I found an article that can tell us how to create Stored Process for this problem. My answer is addition to the article.
The approach is base on execute java methods from sas programm.
1. Prerare setPasswd.java class
I've modified class from article. Separate code to connect to metadata server and create InternalLogin
import java.rmi.RemoteException;
import com.sas.metadata.remote.AssociationList;
import com.sas.metadata.remote.CMetadata;
import com.sas.metadata.remote.Person;
import com.sas.metadata.remote.MdException;
import com.sas.metadata.remote.MdFactory;
import com.sas.metadata.remote.MdFactoryImpl;
import com.sas.metadata.remote.MdOMIUtil;
import com.sas.metadata.remote.MdOMRConnection;
import com.sas.metadata.remote.MdObjectStore;
import com.sas.metadata.remote.MetadataObjects;
import com.sas.metadata.remote.PrimaryType;
import com.sas.metadata.remote.Tree;
import com.sas.meta.SASOMI.ISecurity_1_1;
import com.sas.iom.SASIOMDefs.VariableArray2dOfStringHolder;
public class setPasswd {
String serverName = null;
String serverPort = null;
String serverUser = null;
String serverPass = null;
MdOMRConnection connection = null;
MdFactoryImpl _factory = null;
ISecurity_1_1 iSecurity = null;
MdObjectStore objectStore = null;
Person person = null;
public int connectToMetadata(String name, String port, String user, String pass){
try {
serverName = name;
serverPort = port;
serverUser = user;
serverPass = pass;
_factory = new MdFactoryImpl(false);
connection = _factory.getConnection();
connection.makeOMRConnection(serverName, serverPort, serverUser, serverPass);
iSecurity = connection.MakeISecurityConnection();
return 0;
}catch(Exception e){
return 1;
}
}
public setPasswd(){};
public int changePasswd(String IdentityName, String IdentityPassword) {
try
{
//
// This block obtains the person metadata ID that is needed to change the password
//
// Defines the GetIdentityInfo 'ReturnUnrestrictedSource' option.
final String[][] options ={{"ReturnUnrestrictedSource",""}};
// Defines a stringholder for the info output parameter.
VariableArray2dOfStringHolder info = new VariableArray2dOfStringHolder();
// Issues the GetInfo method for the provided iSecurity connection user.
iSecurity.GetInfo("GetIdentityInfo","Person:"+IdentityName, options, info);
String[][] returnArray = info.value;
String personMetaID = new String();
for (int i=0; i< returnArray.length; i++ )
{
System.out.println(returnArray[i][0] + "=" + returnArray[i][1]);
if (returnArray[i][0].compareTo("IdentityObjectID") == 0) {
personMetaID = returnArray[i][1];
}
}
objectStore = _factory.createObjectStore();
person = (Person) _factory.createComplexMetadataObject(objectStore, IdentityName, MetadataObjects.PERSON, personMetaID);
iSecurity.SetInternalPassword(IdentityName, IdentityPassword);
person.updateMetadataAll();
System.out.println("Password has been changed.");
return 0; // success
}
catch (MdException e)
{
Throwable t = e.getCause();
if (t != null)
{
String ErrorType = e.getSASMessageSeverity();
String ErrorMsg = e.getSASMessage();
if (ErrorType == null)
{
// If there is no SAS server message, write a Java/CORBA message.
}
else
{
// If there is a message from the server:
System.out.println(ErrorType + ": " + ErrorMsg);
}
if (t instanceof org.omg.CORBA.COMM_FAILURE)
{
// If there is an invalid port number or host name:
System.out.println(e.getLocalizedMessage());
}
else if (t instanceof org.omg.CORBA.NO_PERMISSION)
{
// If there is an invalid user ID or password:
System.out.println(e.getLocalizedMessage());
}
}
else
{
// If we cannot find a nested exception, get message and print.
System.out.println(e.getLocalizedMessage());
}
// If there is an error, print the entire stack trace.
e.printStackTrace();
}
catch (RemoteException e)
{
// Unknown exception.
e.printStackTrace();
}
catch (Exception e)
{
// Unknown exception.
e.printStackTrace();
}
System.out.println("Failure: Password has NOT been changed.");
return 1; // failure
}
}
2. Resolve depends
Pay attention to imports in class. To enable execute the code below necessary set CLASSPATH enironment variable.
On linux you can add the next command in %SASConfig%/Lev1/level_env_usermods.sh:
export CLASSPATH=$CLASSPATH:%pathToJar%
On Windows you can add/change environment variable by Advanced system settings
So where should you search jar files? They are in folder:
%SASHome%/SASVersionedJarRepository/eclipse/plugins/
Which files i should include in path?
I've include all that used in OMI(Open Metadata Interface).Also I've added log4j.jar (not working without this jar. Your promts will be helpful):
sas.oma.joma.jar
sas.oma.joma.rmt.jar
sas.oma.omi.jar
sas.svc.connection.jar
sas.core.jar
sas.entities.jar
sas.security.sspi.jar
log4j.jar
setPasswd.jar (YOUR JAR FROM THE NEXT STEP!)
Choose files from nearest release. Example:
Here I'm set file from v940m3f (fix release).
Other ways is here.
3. Compile setPasswd.jar
I'm tried use internal javac.exe into SAS, but it's not worked properly. So ou need to download JDK to compile jars. I've create Bat-file:
"C:\Program Files\Java\jdk1.8.0_121\bin\javac.exe" -source 1.7 -target 1.7 setPasswd.java
"C:\Program Files\Java\jdk1.8.0_121\bin\jar" -cf setPasswd.jar setPasswd.class
Paramethers -source and -target will helpful if your version of JDK is upper, that usses in SAS. Version of "sas"-java you can see by:
PROC javainfo all;
run;
Search the next string in log:
java.vm.specification.version = 1.7
4. Finally. SAS Base call
Now we can call Java code by this method (All methods available here):
data test;
dcl javaobj j ("setPasswd");
j.callIntMethod("connectToMetadata", "%SERVER%", "%PORT%", "%ADMIN%", "%{SAS002}HASHPASSORPASS%", rc1);
j.callIntMethod("changePasswd", "testPassLogin", "pass1", rc2);
j.delete();
run;
In log:
UserClass=Normal
AuthenticatedUserid=Unknown
IdentityName=testPass
IdentityType=Person
IdentityObjectID=A56RQPC2.AP00000I
Password has been changed.
Now time to test. Create new user with no passwords.
Execute code:
data test;
dcl javaobj j ("setPasswd");
j.callIntMethod("connectToMetadata", "&server.", "&port.", "&adm", "&pass", rc1);
j.callIntMethod("changePasswd", "TestUserForStack", "Overflow", rc2);
j.delete();
run;
Now our user has InternalLogin object.
Thanx.

Why does SQL Server CLR procedure hang in GetResponse() call to web service

Environment: C#, .Net 3.5, Sql Server 2005
I have a method that works in a stand-alone C# console application project. It creates an XMLElement from data in the database and uses a private method to send it to a web service on our local network. When run from VS in this test project, it runs in < 5 seconds.
I copied the class into a CLR project, built it, and installed it in SQL Server (WITH PERMISSION_SET = EXTERNAL_ACCESS). The only difference is the SqlContext.Pipe.Send() calls that I added for debugging.
I am testing it by using an EXECUTE command one stored procedure (in the CLR) from an SSMS query window. It never returns. When I stop execution of the call after a minute, the last thing displayed is "Calling GetResponse() using http://servername:53694/odata.svc/Customers/". Any ideas as to why the GetResponse() call doesn't return when executing within SQL Server?
private static string SendPost(XElement entry, SqlString url, SqlString entityName)
{
// Send the HTTP request
string serviceURL = url.ToString() + entityName.ToString() + "/";
HttpWebRequest request = (HttpWebRequest)HttpWebRequest.Create(serviceURL);
request.Method = "POST";
request.Accept = "application/atom+xml,application/xml";
request.ContentType = "application/atom+xml";
request.Timeout = 20000;
request.Proxy = null;
using (var writer = XmlWriter.Create(request.GetRequestStream()))
{
entry.WriteTo(writer);
}
try
{
SqlContext.Pipe.Send("Calling GetResponse() using " + request.RequestUri);
WebResponse response = request.GetResponse();
SqlContext.Pipe.Send("Back from GetResponse()");
/*
string feedData = string.Empty;
Stream stream = response.GetResponseStream();
using (StreamReader streamReader = new StreamReader(stream))
{
feedData = streamReader.ReadToEnd();
}
*/
HttpStatusCode StatusCode = ((HttpWebResponse)response).StatusCode;
response.Close();
if (StatusCode == HttpStatusCode.Created /* 201 */ )
{
return "Created # Location= " + response.Headers["Location"];
}
return "Creation failed; StatusCode=" + StatusCode.ToString();
}
catch (WebException ex)
{
return ex.Message.ToString();
}
finally
{
if (request != null)
request.Abort();
}
}
The problem turned out to be the creation of the request content from the XML. The original:
using (var writer = XmlWriter.Create(request.GetRequestStream()))
{
entry.WriteTo(writer);
}
The working replacement:
using (Stream requestStream = request.GetRequestStream())
{
using (var writer = XmlWriter.Create(requestStream))
{
entry.WriteTo(writer);
}
}
You need to dispose the WebResponse. Otherwise, after a few calls it goes to timeout.
You are asking for trouble doing this in the CLR. And you say you are calling this from a trigger? This belongs in the application tier.
Stuff like this is why when the CLR functionality came out, DBAs were very concerned about how it would be misused.

Using the Reporting Services Web Service, how do you get the permissions of a particular user?

Using the SQL Server Reporting Services Web Service, how can I determine the permissions of a particular domain user for a particular report? The user in question is not the user that is accessing the Web Service.
I am accessing the Web Service using a domain service account (lets say MYDOMAIN\SSRSAdmin) that has full permissions in SSRS. I would like to programmatically find the permissions of a domain user (lets say MYDOMAIN\JimBob) for a particular report.
The GetPermissions() method on the Web Service will return a list of permissions that the current user has (MYDOMAIN\SSRSAdmin), but that is not what I'm looking for. How can I get this same list of permissions for MYDOMAIN\JimBob? I will not have the user's domain password, so using their credentials to call the GetPermissions() method is not an option. I am however accessing this from an account that has full permissions, so I would think that theoretically the information should be available to it.
SSRS gets the NT groups from the users' NT login token. This is why when you are added to a new group, you are expected to log out and back in. The same applies to most Windows checks (SQL Server, shares, NTFS etc).
If you know the NT group(s)...
You can query the ReportServer database directly. I've lifted this almost directly out of one of our reports which we use to check folder security (C.Type = 1). Filter on U.UserName.
SELECT
R.RoleName,
U.UserName,
C.Path
FROM
ReportServer.dbo.Catalog C WITH (NOLOCK) --Parent
JOIN
ReportServer.dbo.Policies P WITH (NOLOCK) ON C.PolicyID = P.PolicyID
JOIN
ReportServer.dbo.PolicyUserRole PUR WITH (NOLOCK) ON P.PolicyID = PUR.PolicyID
JOIN
ReportServer.dbo.Users U WITH (NOLOCK) ON PUR.UserID = U.UserID
JOIN
ReportServer.dbo.Roles R WITH (NOLOCK) ON PUR.RoleID = R.RoleID
WHERE
C.Type = 1
look into "GetPolicies Method" you can see at the following link.
http://msdn.microsoft.com/en-us/library/reportservice2010.reportingservice2010.getpolicies.aspx
Hopefully this will get you started. I use it when copying Folder structure, and Reports from an old server to a new server when I want to 'migrate' my SSRS items from the Source to the Destination Server. It is a a Method to Get the Security Policies for an item on one server, and then set the Security Policies for an identical item on another server, after I have copied the item from the Source Server to the Destination Server. You have to set your own Source and Destination Server Names.
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Web.Services.Protocols; //<=== required for SoapException
namespace SSRS_WebServices_Utility
{
internal static class TEST
{
internal static void GetPoliciesForAnItem_from_Source_ThenSetThePolicyForTheItem_on_Destination(string itemPath)
{
string sSourceServer = "SOURCE-ServerName";
Source_ReportService2010.ReportingService2010 sourceRS = new Source_ReportService2010.ReportingService2010();
sourceRS.Credentials = System.Net.CredentialCache.DefaultCredentials;
sourceRS.Url = #"http://" + sSourceServer + "/reportserver/reportservice2010.asmx";
string sDestinationServer = "DESTINATION-ServerName";
Destination_ReportService2010.ReportingService2010 DestinationRS = new Destination_ReportService2010.ReportingService2010();
DestinationRS.Credentials = System.Net.CredentialCache.DefaultCredentials;
DestinationRS.Url = #"http://" + sDestinationServer + "/reportserver/reportservice2010.asmx";
Boolean val = true;
Source_ReportService2010.Policy[] curPolicy = null;
Destination_ReportService2010.Policy[] newPolicy = null;
try
{
curPolicy = new Source_ReportService2010.Policy[1];
curPolicy = sourceRS.GetPolicies(itemPath, out val); //e.g. of itemPath: "/B2W/001_OLD_PuertoRicoReport"
//DestinationRS.SetPolicies(itemPath, newPolicy);
int iCounter = 0;
//int iMax = curPolicy.Length;
newPolicy = new Destination_ReportService2010.Policy[curPolicy.Length];
foreach (Source_ReportService2010.Policy p in curPolicy)
{
//create the Policy
Destination_ReportService2010.Policy pNew = new Destination_ReportService2010.Policy();
pNew.GroupUserName = p.GroupUserName;
pNew.GroupUserName = p.GroupUserName;
Destination_ReportService2010.Role rNew = new Destination_ReportService2010.Role();
rNew.Description = p.Roles[0].Description;
rNew.Name = p.Roles[0].Name;
//create the Role, which is part of the Policy
pNew.Roles = new Destination_ReportService2010.Role[1];
pNew.Roles[0]=rNew;
newPolicy[iCounter] = pNew;
iCounter += 1;
}
DestinationRS.SetPolicies(itemPath, newPolicy);
Debug.Print("whatever");
}
catch (SoapException ex)
{
Debug.Print("SoapException: " + ex.Message);
}
catch (Exception Ex)
{
Debug.Print("NON-SoapException: " + Ex.Message);
}
finally
{
if (sourceRS != null)
sourceRS.Dispose();
if (DestinationRS != null)
DestinationRS.Dispose();
}
}
}
}
To invoke it use the following:
TEST.GetPoliciesForAnItem_from_Source_ThenSetThePolicyForTheItem_on_Destination("/FolderName/ReportName");
Where you have to put your own SSRS Folder Name and Report Name, i.e. the Path to the item.
In fact I use a method that loops through all the items in the Destination folder that then calls the method like this:
internal static void CopyTheSecurityPolicyFromSourceToDestinationForAllItems_2010()
{
string sDestinationServer = "DESTINATION-ServerName";
Destination_ReportService2010.ReportingService2010 DestinationRS = new Destination_ReportService2010.ReportingService2010();
DestinationRS.Credentials = System.Net.CredentialCache.DefaultCredentials;
DestinationRS.Url = #"http://" + sDestinationServer + "/reportserver/reportservice2010.asmx";
// Return a list of catalog items in the report server database
Destination_ReportService2010.CatalogItem[] items = DestinationRS.ListChildren("/", true);
// For each FOLDER, debug Print some properties
foreach (Destination_ReportService2010.CatalogItem ci in items)
{
{
Debug.Print("START----------------------------------------------------");
Debug.Print("Object Name: " + ci.Name);
Debug.Print("Object Type: " + ci.TypeName);
Debug.Print("Object Path: " + ci.Path);
Debug.Print("Object Description: " + ci.Description);
Debug.Print("Object ID: " + ci.ID);
Debug.Print("END----------------------------------------------------");
try
{
GetPoliciesForAnItem_from_Source_ThenSetThePolicyForTheItem_on_Destination(ci.Path);
}
catch (SoapException e)
{
Debug.Print("SoapException START----------------------------------------------------");
Debug.Print(e.Detail.InnerXml);
Debug.Print("SoapException END----------------------------------------------------");
}
catch (Exception ex)
{
Debug.Print("ERROR START----------------------------------------------------");
Debug.Print(ex.GetType().FullName);
Debug.Print(ex.Message);
Debug.Print("ERROR END----------------------------------------------------");
}
}
}
}

Virtual Server IIS WMI Problem

I have been tasked with finding out what is causing an issue with this bit of code:
public static ArrayList GetEthernetMacAddresses()
{
ArrayList addresses = new ArrayList();
ManagementClass mc = new ManagementClass("Win32_NetworkAdapter");
// This causes GetInstances(options)
// to return all subclasses of Win32_NetworkAdapter
EnumerationOptions options = new EnumerationOptions();
options.EnumerateDeep = true;
foreach (ManagementObject mo in mc.GetInstances(options)) {
string macAddr = mo["MACAddress"] as string;
string adapterType = mo["AdapterType"] as string;
if (!StringUtil.IsBlank(macAddr) && !StringUtil.IsBlank(adapterType))
{
if (adapterType.StartsWith("Ethernet")) {
addresses.Add(macAddr);
}
}
}
return addresses;
}
On our (Win2003) virtual servers, this works when run as part of a console application but not from a web service running on IIS (on that same machine).
Alternatively, I can use this code in a web service on IIS (on the virtual server) and get the correct return values:
public static string GetMacAddresses()
{
ManagementClass mgmt = new ManagementClass(
"Win32_NetworkAdapterConfiguration"
);
ManagementObjectCollection objCol = mgmt.GetInstances();
foreach (ManagementObject obj in objCol)
{
if ((bool)obj["IPEnabled"])
{
if (sb.Length > 0)
{
sb.Append(";");
}
sb.Append(obj["MacAddress"].ToString());
}
obj.Dispose();
}
}
Why does the second one work and not the first one?
Why only when called through an IIS web service on a virtual machine?
Any help would be appreciated.
UPDATE: After much telephone time with all different levels of MS Support, the've come to the conclusion that this is "As Designed".
Since it is on a driver level for the virtual network adapter driver, the answer was that we should change our code "to work around the issue".
This means that you cannot reliable test code on virtual servers unless you with the same code that you use on physical servers, since we can't guarantee that the servers are exact replicas...
Okay, so I wrote this code to test the issue:
public void GetWin32_NetworkAdapter()
{
DataTable dt = new DataTable();
dt.Columns.Add("AdapterName", typeof(string));
dt.Columns.Add("ServiceName", typeof(string));
dt.Columns.Add("AdapterType", typeof(string));
dt.Columns.Add("IPEnabled", typeof(bool));
dt.Columns.Add("MacAddress", typeof(string));
//Try getting it by Win32_NetworkAdapterConfiguration
ManagementClass mgmt = new ManagementClass("Win32_NetworkAdapter");
EnumerationOptions options = new EnumerationOptions();
options.EnumerateDeep = true;
ManagementObjectCollection objCol = mgmt.GetInstances(options);
foreach (ManagementObject obj in objCol)
{
DataRow dr = dt.NewRow();
dr["AdapterName"] = obj["Caption"].ToString();
dr["ServiceName"] = obj["ServiceName"].ToString();
dr["AdapterType"] = obj["AdapterType"];
dr["IPEnabled"] = (bool)obj["IPEnabled"];
if (obj["MacAddress"] != null)
{
dr["MacAddress"] = obj["MacAddress"].ToString();
}
else
{
dr["MacAddress"] = "none";
}
dt.Rows.Add(dr);
}
gvConfig.DataSource = dt;
gvConfig.DataBind();
}
When it's run on a physical IIS box I get this:
Physical IIS server http://img14.imageshack.us/img14/8098/physicaloutput.gif
Same code on Virtual IIS server:
Virtual server http://img25.imageshack.us/img25/4391/virtualoutput.gif
See a difference? It's on the first line. The virtual server doesn't return the "AdapterType" string. Which is why the original code was failing.
This brings up an interesting thought. If Virtual Server is supposed to be an "virtual" representation of a real IIS server, why doesn't it return the same values?
Why are the two returning different results? It's possible that due to the different user accounts, you'll get different results running from the console and from a service.
Why does (1) fail and (2) work? Is it possible that a null result for adapterType return a null value? If so, would the code handle this condition?