I have a sharepoint 2010 list that I'm using to track servers and the app installed on them. I have writen a c# console program that reads the server name from the list and then queries the servers using WMI to keep the list current. The text fields update with out a problem but I am having a problem with a column that contains a lookup to a 2nd sharepoint list. the 2nd list has a list of application platforms ( Dot Net 4.5, Java, Sharepoint, Biztalk) that could be installed on a server. When I update the Lookup field everything looks good while tracing in Vistal Studio but the sharepoint data never actualy updates.
The line svr.InstalledPlatforms.Add(plat); doesn't throw an error and the collection gets a added too.
svr is the row in the sharepoint list, InstalledPlatforms is the mult-select lookup, plat is the row in the lookup table called platforms
The responses from:
dc.UpdateObject(svr);
var responses = dc.SaveChanges();
all come back with 204 - no error
// setup connection to SharePoint. the credentials need to be set for NTLM security AKAServiceReference.ApplicationKnowledgeAreaDataContext dc = new AKAServiceReference.ApplicationKnowledgeAreaDataContext(new Uri(AppSettings.Default.AKASitePath)); dc.Credentials = System.Net.CredentialCache.DefaultCredentials; // loop through each server in the server list and use WMI to query those servers foreach (var svr in dc.ServerList) { // skip server names with odd characters or servers that are retired if (svr.ServerName.Contains("*") || svr.ServerName.Contains("/") || svr.StatusValue == "Retired") continue; Console.WriteLine("Server: {0}", svr.ServerName); try { bool changed = false; string svrName = svr.ServerName; ManagementScope scope = new ManagementScope(@"\\" + svrName + @"\root\cimv2"); SelectQuery query = new SelectQuery(); // get the values that are returned from the Win32_OperatingSystem - operating system type data query.QueryString = "select * from Win32_OperatingSystem"; ManagementObjectSearcher searcher = new ManagementObjectSearcher(scope, query); ManagementObjectCollection queryCollection = searcher.Get(); foreach (ManagementObject mgmtobj in queryCollection) { // Display the remote computer information Console.WriteLine("Operating System: {0}", mgmtobj.Properties["Caption"].Value); Console.WriteLine("Memory : {0:f1} GB", float.Parse(mgmtobj.Properties["TotalVisibleMemorySize"].Value.ToString()) / 1024 / 1024); if (svr.OperatingSystem.CompareTo( mgmtobj.Properties["Caption"].Value) !=0 ) { svr.OperatingSystem = mgmtobj.Properties["Caption"].Value.ToString(); changed = true; } float mem = float.Parse(mgmtobj.Properties["TotalVisibleMemorySize"].Value.ToString()) / 1024 / 1024; string tempMem = mem.ToString("0.00"); if (svr.Memory.CompareTo(tempMem) != 0) { svr.Memory = tempMem; changed = true; } } // get the values that are returned from the Win32_ComputerSystem - hardware type data query.QueryString = "Select * from Win32_ComputerSystem"; searcher = new ManagementObjectSearcher(scope, query); queryCollection = searcher.Get(); foreach (ManagementObject mgmtobj in queryCollection) { Console.WriteLine("NumberOfProcessors:" + mgmtobj.Properties["NumberOfProcessors"].Value); //Console.WriteLine("NumberOfLogicalProcessors:" + mgmtobj.Properties["NumberOfLogicalProcessors"].Value); if (svr.NumberOfProcessors.CompareTo(mgmtobj.Properties["NumberOfProcessors"].Value.ToString()) != 0) { svr.NumberOfProcessors = mgmtobj.Properties["NumberOfProcessors"].Value.ToString(); changed = true; } } if (svr.ServerTypeValue == "App Server") { ManagementScope ms = new ManagementScope(); ms.Path.Server = svr.ServerName; ms.Path.NamespacePath = @"root\default"; ms.Options.EnablePrivileges = true; ms.Connect(); ManagementClass mc = new ManagementClass("stdRegProv"); mc.Scope = ms; ManagementBaseObject mbo; mbo = mc.GetMethodParameters("EnumKey"); mbo.SetPropertyValue("sSubKeyName", @"SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\"); string[] subkeys = (string[])mc.InvokeMethod("EnumKey", mbo, null).Properties["sNames"].Value; ManagementBaseObject mboS; string keyValue; List<string> nmns = new List<string>(); foreach (string strKey in subkeys) { mboS = mc.GetMethodParameters("GetStringValue"); mboS.SetPropertyValue("sSubKeyName", @"SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\" + strKey); mboS.SetPropertyValue("sValueName", "DisplayName"); var x = mc.InvokeMethod("GetStringValue", mboS, null); keyValue = x.ToString(); var y = x["sValue"]; string ys = ""; if (y != null) ys = y.ToString(); if (!strKey.Contains("{")) { nmns.Add(strKey); } else { nmns.Add(ys); } } foreach (AKAServiceReference.PlatformItem plat in dc.Platform) { if (svr.InstalledPlatforms.Contains(plat) && !nmns.Contains(plat.WMI_Name)) { // need to remove platform from server since its not in wmi results svr.InstalledPlatforms.Remove(plat); changed = true; } else if (nmns.Contains(plat.WMI_Name) && !svr.InstalledPlatforms.Contains(plat)) { // add to list since in WMI but not in platforms changed = true; svr.InstalledPlatforms.Add(plat); } } } if (changed) { dc.UpdateObject(svr); var responses = dc.SaveChanges(); foreach (var response in responses) { string errormsg = "Good"; if (response.Error != null) errormsg = response.Error.Message; Console.WriteLine("Response {0} error {1} ", response.StatusCode, errormsg); } } } catch (System.Runtime.InteropServices.COMException ce) { // this is a RPC server is unavailable // more than likely its not a valid server name // so we move to the next server Console.WriteLine("Error communicating with server {0} error message is {1}", svr.ServerName, ce.Message); } catch (Exception ex) { Console.WriteLine("Error querying server {0} error message is {1}", svr.ServerName, ex.Message); }