We're trying to get the information of GPOs of our computers. Therefore we want to use c# - and not gpresult.exe (because it can be executed in system context...).
Well, as I found out there's a DLL Microsoft.GroupPolicy.Management.dll that can be imported in C#. It sounded too easy:
using Microsoft.GroupPolicy;
[...]
GPRsop rsop = new GPRsop(RsopMode.Logging, "root\\RSOP\\Computer");
rsop.LoggingComputer = "MyComputer";
rsop.LoggingUser = "domain\\user";
rsop.LoggingMode = LoggingMode.Computer;
rsop.CreateQueryResults();
rsop.GenerateReportToFile(ReportType.Xml, "C:\\Temp\\test.xml");
As output file I get this one:
<?xml version="1.0" encoding="utf-16"?>
<Rsop xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns="http://www.microsoft.com/GroupPolicy/Rsop">
<ReadTime>2013-05-06T13:28:17.1529206Z</ReadTime>
<DataType>LoggedData</DataType>
</Rsop>
Anyone here who ever worked with this DLL and can give me some hints?
Thanks in advance!
Cheers
You should execute rsop.CreateQueryResults(), before you generate the report. This requires the LoggingMode, LoggingUser and LoggingComputer properties to be set.
GPRsop rsop = new GPRsop(RsopMode.Logging, null);
rsop.LoggingMode = LoggingMode.Computer;
rsop.LoggingComputer = Environment.GetEnvironmentVariable("COMPUTERNAME");
rsop.LoggingUser = Environment.UserDomainName + #"\" + Environment.GetEnvironmentVariable("USERNAME");
rsop.CreateQueryResults();
var xml = rsop.GenerateReport(ReportType.Xml);
GPMGMTLib used
GPM gpm = new GPM();
var rsop = gpm.GetRSOP(GPMRSOPMode.rsopLogging, null, 0);
rsop.LoggingFlags = 0x20000;
rsop.LoggingComputer = Environment.GetEnvironmentVariable("COMPUTERNAME");
rsop.LoggingUser = Environment.UserDomainName + #"\" + Environment.GetEnvironmentVariable("USERNAME");
rsop.CreateQueryResults();
object cancel = new GPMAsyncCancel();
var result = rsop.GenerateReport(GPMReportType.repXML, null, out cancel);
string xml = result.Result;
using GPMGMTLib;
GPM groupPolicyManagement = new GPM();
IGPMConstants groupPolicyConstants = groupPolicyManagement.GetConstants();
GPMRSOP rsop = groupPolicyManagement.GetRSOP(groupPolicyConstants.RSOPModeLogging, null, 0);
rsop.LoggingComputer = "MyComputer";
rsop.LoggingUser = "domain\\user";
rsop.CreateQueryResults();
rsop.GenerateReportToFile(groupPolicyConstants.ReportXML, "C:\\Temp\\test.xml");
Related
I got a “XPath Injection” issue from Fortify scan for below code,
string username = string.Empty;
string password = string.Empty;
string officePrefix = "";
if (!String.IsNullOrEmpty(securityNode.Prefix))
{
officePrefix = securityNode.Prefix + ":";
ns.AddNamespace(securityNode.Prefix, securityNode.Namespace);
}
var regexPattern =
ConfigurationManager.AppSettings["xxx"];
var regexItem = new Regex(regexPattern, RegexOptions.None);
if(regexItem.IsMatch(officePrefix ))
{
//wsse:UsernameToken
XmlNode usernameTokenNode = securityNode.SelectSingleNode(officePrefix +
"UsernameTkn", ns);
username = usernameTokenNode.SelectSingleNode(officePrefix + "name", ns).InnerText;
password = usernameTokenNode.SelectSingleNode(officePrefix + "Pwd", ns).InnerText;
above code i am getting issue from ( XmlNode usernameTokenNode = securityNode.SelectSingleNode(officePrefix +
"UsernameToken", ns);) this line of code. So, I tried to use regex and as you can see in the code. Even though the xpath injection issue still persists. Can any one kindly give a solution for the xpath injection issue.
You don't need to re-use the namespace alias from the actual XML. you can use your own. The only thing is that the actual namespace must be the same
string username = string.Empty;
string password = string.Empty;
const string officePrefix = "myPrefix";
bool hasPrefix = !string.IsNullOrEmpty(securityNode.Namespace);
if (hasPrefix)
{
ns.AddNamespace(officePrefix, securityNode.Namespace);
}
XmlNode usernameTokenNode = securityNode.SelectSingleNode(hasPrefix ? officePrefix + ":UsernameTkn" : "UsernameTkn", ns);
username = usernameTokenNode.SelectSingleNode(hasPrefix ? officePrefix + ":name" : "name", ns).InnerText;
password = usernameTokenNode.SelectSingleNode(hasPrefix ? officePrefix + ":Pwd" : "Pwd", ns).InnerText;
I note that XName and XNode are newer and much easier to use, they are in the System.Xml.Linq library.
I'm populating fields data from database with bartender but I'm not able to do same while changing database from code,
e.g. There is a template called TestLBL.btw and in the template we have configured database field say TestDB.Name field now I've another database say TestDB2 and that have exact same fields as TestDB now I just wanted to print label with same field with different database(TestDB2) using c# code but that doesn't works :(
below is my sample code :
btnEngine = new Engine();
btnEngine.Start();
lblDoc = btnEngine.Documents.Open(ConfigurationManager.AppSettings["BarTenderTemplate_Path"] + templateName);
var msg = new Messages();
var resolution = new Resolution(300);
string connectString = ConfigurationManager.ConnectionStrings["TestDB2"].ConnectionString;
SqlConnectionStringBuilder builder = new SqlConnectionStringBuilder(connectString);
lblDoc.DatabaseConnections[0].Name = builder.InitialCatalog;
lblDoc.DatabaseConnections[0].Server = builder.DataSource;
lblDoc.DatabaseConnections[0].UserID = builder.UserID;
lblDoc.DatabaseConnections[0].SetPassword(builder.Password);
lblDoc.DatabaseConnections.SetDatabaseConnection(lblDoc.DatabaseConnections[0]);
lblDoc.DatabaseConnections.QueryPrompts["pRec_Key"].Value = Rec_key.ToString();
lblDoc.DatabaseConnections.QueryPrompts["pImage_Path"].Value = Image_Path;
var fileName = templateName.Split('.')[0] + "_" + Rec_key.ToString() + ".pdf";
var fileFullPath = Path.GetDirectoryName(ConfigurationManager.AppSettings["BarTenderTemplate_Path"]) + "\\" + templateName.Split('.')[0] + "_" + Rec_key.ToString() + ".pdf";
var result = lblDoc.ExportPrintPreviewToFile(Path.GetDirectoryName(ConfigurationManager.AppSettings["BarTenderTemplate_Path"]), fileName, ImageType.PDF
, ColorDepth.ColorDepth24bit, resolution, Color.White, OverwriteOptions.Overwrite, true, true, out msg);
lblDoc.Close(SaveOptions.SaveChanges);
It throws an error in below line, without any inner exception,
var result = lblDoc.ExportPrintPreviewToFile(Path.GetDirectoryName(ConfigurationManager.AppSettings["BarTenderTemplate_Path"]), fileName, ImageType.PDF
, ColorDepth.ColorDepth24bit, resolution, Color.White, OverwriteOptions.Overwrite, true, true, out msg);
Any help would be appreciated.!
I could not comment the post so i'll ask my question here:
What is the error message in this line?
var result =
lblDoc.ExportPrintPreviewToFile(
Path.GetDirectoryName(ConfigurationManager.AppSettings["BarTenderTemplate_Path"]),
fileName,
ImageType.PDF,
ColorDepth.ColorDepth24bit,
resolution,
Color.White,
OverwriteOptions.Overwrite, true, true, out msg);
Did you set up TestDB2 in your BTW file database?
string connectString = ConfigurationManager.ConnectionStrings["TestDB2"].ConnectionString;
Did your fileName valid?
var fileName = templateName.Split('.')[0] + "_" + Rec_key.ToString() + ".pdf";
I am having an issue when attempting to create a new user in active directory. I followed the steps provided in this link for using PrincipalContext (with the exception that I am only doing one user at a time when they are hired and entered into the system and not multiple so no loop is required). I am also using a UserPrincipal Extender.
Here is the code that I have:
protected void CreateUserPE()
{
try
{
PrincipalContext userCtx = new PrincipalContext(ContextType.Domain, DomainFQDN, DomainFull);
string UserName = txtFirstName.Text.ToLower() + " " + txtLastName.Text.ToLower();
string password = "superSecretPassword";
UserPrincipalsEx newUser = new UserPrincipalsEx(userCtx, UserName, password, true);
newUser.SamAccountName = txtFirstName.Text.ToLower() + "." + txtLastName.Text.ToLower();
newUser.UserPrincipalName = txtFirstName.Text.ToLower() + "." + txtLastName.Text.ToLower() + "#rasm.com";
newUser.EmployeeId = txtEmpID.Text;
newUser.LastName = txtLastName.Text;
newUser.GivenName = txtFirstName.Text;
newUser.DisplayName = txtFirstName.Text + " " + txtLastName.Text;
newUser.Name = txtFirstName.Text + " " + txtLastName.Text;
newUser.SetPassword(password);
newUser.HomePostalAddress = txtAddress.Text + ", " + txtCity.Text + ", " + txtState.Text + ", " + txtZip.Text;
newUser.CountryName = txtCountry.Text;
newUser.HomePhone = txtHomePhone.Text;
newUser.MobilePhone = txtMobilePhone.Text;
newUser.DateOfBirth = txtDOB.Text;
newUser.EmergencyContact = txtEmergencyCnt.Text;
newUser.EmergencyPhone = txtContactPhone.Text;
newUser.Relationship = ddlRelationship1.SelectedItem.ToString();
newUser.EmergencyContact2 = txtEmergencyCnt2.Text;
newUser.EmergencyPhone2 = txtContactPhone2.Text;
newUser.Relationship2 = ddlRelationship2.SelectedItem.ToString();
newUser.EyeColor = ddlEyeColor.SelectedItem.ToString();
newUser.HairColor = ddlHairColor.SelectedItem.ToString();
newUser.Height = txtHeight.Text;
newUser.Weight = txtWeight.Text;
newUser.Gender = ddlGender.SelectedItem.ToString();
newUser.PersonalEmail = txtPersonalEmail.Text;
newUser.PassportExpires = txtPassportExp.Text;
newUser.HomeBase = ddlHomeStation.SelectedItem.ToString();
newUser.WorkLocation = txtWorkLocation.Text;
newUser.PID = txtPID.Text;
newUser.Team = txtTeam.Text;
newUser.Manager = "CN=" + txtSupervisor.Text + "," + DomainFull;
newUser.Title = ddlJobTitle.SelectedItem.ToString();
newUser.JobCode = txtJobCode.Text;
newUser.PLC = txtPLC.Text;
newUser.BPLC = txtBPLC.Text;
newUser.Specialty = txtSpecialty.Text;
newUser.Position = txtPosition.Text;
newUser.DateOfHire = txtDOH.Text;
newUser.DateOnContract = txtDOC.Text;
newUser.TaskOrder = ddlTaskOrder.SelectedItem.ToString();
newUser.Classification = ddlClass.SelectedIndex.ToString();
newUser.Section = txtSection.Text;
newUser.GatePass = txtGatePass.Text;
newUser.GatePassExpires = txtGatePassExp.Text;
newUser.WorkPhone = txtWorkPhone.Text;
newUser.CompanyEmail = txtCompEmail.Text;
newUser.aKOEmail = txtMilEmail.Text;
newUser.aKOSponsor = txtMilEmailSp.Text;
newUser.CACSponsor = txtCacSponsor.Text;
newUser.CACSponsorEmail = txtCacSponsorEmail.Text;
newUser.CacCardExpires = txtCacExpires.Text;
newUser.Enabled = true;
newUser.ExpirePasswordNow();
newUser.Save();
newUser.Dispose();
}
catch
{
}
}
The program goes all the way to newUser.Save() and then throws the following error in the catch statement:
System.DirectoryServices.AccountManagement.PrincipalOperationException was caught
HResult=-2146233087
Message=The attribute syntax specified to the directory service is invalid.
Source=System.DirectoryServices.AccountManagement
ErrorCode=-2147016693
StackTrace:
at System.DirectoryServices.AccountManagement.ADStoreCtx.Insert(Principal p)
at System.DirectoryServices.AccountManagement.Principal.Save()
at Personnel_Employee.CreateUserPE() in c:\inetpub\wwwroot\TestingFolder\Personnel\Add\Employee.aspx.cs:line 263
InnerException: System.DirectoryServices.DirectoryServicesCOMException
HResult=-2147016693
Message=The attribute syntax specified to the directory service is invalid.
Source=System.DirectoryServices
ErrorCode=-2147016693
ExtendedError=87
ExtendedErrorMessage=00000057: LdapErr: DSID-0C090D11, comment: Error in attribute conversion operation, data 0, v23f0
StackTrace:
at System.DirectoryServices.DirectoryEntry.CommitChanges()
at System.DirectoryServices.AccountManagement.SDSUtils.ApplyChangesToDirectory(Principal p, StoreCtx storeCtx, GroupMembershipUpdater updateGroupMembership, NetCred credentials, AuthenticationTypes authTypes)
InnerException:
Where am I going wrong.
You can not update an attribute with null or empty. I personaly dislike solutions with dummy values. If you are using the context principle just simply check for null or empty and dont update if its the case like:
if (!string.IsNullOrEmpty(txtbox.Text)){ newUser.attributeName = txtbox.Text}
If you are using an directory entry instead of an usercontext you can do something like this:
string adPath = "LDAP://server.domain.com/CN=John,CN=Users,dc=domain,dc=com";
DirectoryEntry userEntry = new DirectoryEntry(adPath);
if (txtBox.text == "")
{
userEntry.Properties["proppertyName"].Clear();
}
else if (!string.IsNullOrEmpty(txtBox.text))
{
userEntry.Properties[attribute.Key].Value = txtBox.text;
}
// dont do a thing when txtBox.Text is empty
It looks like more code but its much easier to make a foreachloop for it if you have a list with all attribute like:
private void UpdateEntryAttributes(DirectoryEntry entry, Dictionary<string, string> attributes)
{
foreach (KeyValuePair<string, string> attribute in attributes)
{
entry.Properties[attribute.Key].Value = attribute.Value;
if (attribute.Value == "")
{
entry.Properties[attribute.Key].Clear();
}
else if (!string.IsNullOrEmpty(attribute.Value))
{
entry.Properties[attribute.Key].Value = attribute.Value;
}
}
This can happen when attempting to write either a null or empty string to an AD field that prohibits it. An easy way to check whether this is the problem is to temporarily replace all such values with a dummy string (length > 0) and then run the code again. If that works, you can attempt a fix by changing the offending value--with AD, sometimes if null doesn't work, then an empty string will work, or vice versa.
I'm trying to retrieve values from an XML file and I find some values are empty.
textBox6, textBox7, textBox14 corresponding element attribute values are empty/null. The error message is Null reference error was unhanded . How can fix this??
private void DisplayFile(string path)
{
var doc = XDocument.Load(path);
var ns = doc.Root.GetDefaultNamespace();
var conn = doc.Root.Element(ns + "connection");
textBox1.Text = conn.Element(ns + "sourceId").Value;
var doc1 = XDocument.Load(path);
var ns1 = doc.Root.GetDefaultNamespace();
var conn1 = doc.Root.Element(ns1 + "connectionContext");
}
If a given element is not present in the XML foo.Element("someNode") will return null. When accessing .Value you get a NullReferenceException.
In order to avoid this NullReferenceException you need to check if the element is not null.
Example with contextType:
var contextType = conn1.Element(ns + "contextType");
if (contextType != null)
{
textBox15.Text = contextType.Value;
}
Update:
You try to load the connectionContext node from the root element. But this node is a child of the source node. You need to first load this node:
var source = doc.Root.Element(ns + "source");
var conn1 = source.Element(ns + "connectionContext");
I find your problem try this (i use string cause didn't want to make textboxes)
var doc = XDocument.Load("C:\\Test\\stovfl.xml");
var ns = doc.Root.GetDefaultNamespace();
var conn = doc.Root.Element(ns + "connection");
string s1 = conn.Element(ns + "sourceId").Value;
string s2 = conn.Element(ns + "username").Value;
var conn1 = doc.Root.Element("source");
var conn2 = conn1.Element("connectionContext");
string s6 = conn2.Element(ns + "organization").Value;
string s7 = conn2.Element(ns + "field").Value;
string s14 = conn2.Element(ns + "description").Value;
string s15 = conn2.Element(ns + "contextType").Value;
problem was that you have connectionContext in source, but try to find it in Root
I am trying to use this code to get changes in a site collection. But i don't know how to get the databaseId.
SiteData.SiteData siteData = new SiteData.SiteData();
siteData.UseDefaultCredentials = true;
siteData.Url = "http://localhost:333/_vti_bin/sitedata.asmx";
string lastChangeID = String.Empty;
string result = siteData.GetContent(SiteData.ObjectType.SiteCollection, "", "", "", false, false, ref lastChangeID);
XmlDocument doc = new XmlDocument();
doc.LoadXml(result);
string startChangeId = string.Empty;
string endChangeId = doc.ChildNodes[0].ChildNodes[0].Attributes["ChangeId"].Value;
bool moreChanges;
string databaseId = "";
string result2 = siteData.GetChanges(SiteData.ObjectType.SiteCollection, databaseId, ref startChangeId, ref endChangeId, 5, out moreChanges);
MessageBox.Show(result2);
Thank you for your time.
Edit:
This is the GetContent Result:
You can call the siteData.GetContent method again, this time with the ContentDatabase as ObjectType. The returning CAML should contain the ContentDatabaseId.
string s = siteData.GetContent(SiteData.ObjectType.ContentDatabase, "", "", "", false, false, ref lastChangeID);
You don't need the database Id for calling "GetChanges" method on SiteCollection scope. I use "GetChangesEx" and it works well, this method returns similar information to "GetChanges". Check the protocol specification (PDF) to see the differences: Site Data protocol specification. Also, I think your problem with the "SoapServerException" is the same I had here: other question.
This code example is on the other question I mentioned, but I'll post it here for better readability:
SiteData.SiteDataSoapClient siteDataService = new SiteData.SiteDataSoapClient();
siteDataService.Endpoint.Address = new System.ServiceModel.EndpointAddress("URL/_vti_bin/sitedata.asmx");
siteDataService.ClientCredentials.Windows.ClientCredential = new System.Net.NetworkCredential("username", "password", "domain");
siteDataService.ClientCredentials.Windows.AllowedImpersonationLevel = System.Security.Principal.TokenImpersonationLevel.Impersonation;
String xmlInput = "<GetChanges>" +
"<ObjectType>7</ObjectType>" +
"<ContentDatabaseId/>" +
"<StartChangeId>1;1;69b025ce-96a7-4131-adc0-7da1603e8d24;634439727021700000;47404</StartChangeId>" +
"<EndChangeId>1;1;69b025ce-96a7-4131-adc0-7da1603e8d24;634441802456970000;47472</EndChangeId>" +
"<RequestLoad>100</RequestLoad>" +
"<GetMetadata>False</GetMetadata>" +
"<IgnoreSecurityIfInherit>True</IgnoreSecurityIfInherit>" +
"</GetChanges>";
String result = siteDataService.GetChangesEx(1, xmlInput);