public static void ExtractFromAudit() { IOrganizationService service = MSCRM.GetOrgService(true); // The GUID of the object you want to retirve in this case i am passing contactid var entityId = new Guid("B53045DC-8BF1-E411-80D0-005056A60603"); Console.WriteLine("Retrieving the change history.\n"); // //RetrieveAttributeChangeHistoryRequest req = new RetrieveAttributeChangeHistoryRequest(); //req.Target = new Microsoft.Xrm.Sdk.EntityReference("quote", new Guid("592AF7E6-ADC1-E011-8D7C-1CC1DE79838E")); //req.AttributeLogicalName = "totallineitemamount"; //RetrieveAttributeChangeHistoryResponse resp = (RetrieveAttributeChangeHistoryResponse)service.Execute(req); // Retrieve the audit history for the account and display it. RetrieveRecordChangeHistoryRequest changeRequest = new RetrieveRecordChangeHistoryRequest(); changeRequest.Target = new Microsoft.Xrm.Sdk.EntityReference("quote", entityId); RetrieveRecordChangeHistoryResponse changeResponse = (RetrieveRecordChangeHistoryResponse)service.Execute(changeRequest); AuditDetailCollection details = changeResponse.AuditDetailCollection; foreach (AttributeAuditDetail detail in details.AuditDetails) { DisplayAuditDetails(detail); // Display some of the detail information in each audit record. } }
public List <AuditHistory> GetAuditHistoryForRecord(Guid entityID, string entityLogicalName, string recordKeyValue //,ref List<Log> logs ) { List <AuditHistory> auditHistoryForRecord = new List <AuditHistory>(); RetrieveRecordChangeHistoryRequest changeRequest = new RetrieveRecordChangeHistoryRequest(); changeRequest.Target = new EntityReference(entityLogicalName, entityID); RetrieveRecordChangeHistoryResponse changeResponse = (RetrieveRecordChangeHistoryResponse)_service.Execute(changeRequest); AuditDetailCollection details = changeResponse.AuditDetailCollection; foreach (AuditDetail detail in details.AuditDetails) { List <AuditHistory> records = GetRecordChanges(detail, recordKeyValue); auditHistoryForRecord.AddRange(records); //if (logs.Contains(new Log() { recordId = entityID })) //{ // logs.Find(x => x.recordId.Equals(entityID)).AddNumberOfChanges(records.Count); //} //else //{ // Log logRecord = new Log() { recordId = entityID, RecordKeyValue = recordKeyValue, NumberOfChanges = records.Count }; // logs.Add(logRecord); //} } return(auditHistoryForRecord); }
/// <summary> /// Extract the audit history for the record and a specific Field /// </summary> /// <param name="entityID">ID of the Account</param> /// <param name="identificatorField">Identificator of the Row</param> /// <param name="attributeName">Name of the attribute to retrieve for Audit History</param> /// <param name="fileName">File to write</param> public List <AuditHistory> GetAuditHistoryForRecordAndField(Guid entityID, string entityLogicalName, string attributeName, string recordKeyValue) { List <AuditHistory> auditHistoryForRecord = new List <AuditHistory>(); var attributeChangeHistoryRequest = new RetrieveAttributeChangeHistoryRequest { Target = new EntityReference(entityLogicalName, entityID), AttributeLogicalName = attributeName, }; RetrieveRecordChangeHistoryRequest changeRequest = new RetrieveRecordChangeHistoryRequest(); changeRequest.Target = new EntityReference(entityLogicalName, entityID); RetrieveRecordChangeHistoryResponse changeResponse = (RetrieveRecordChangeHistoryResponse)_service.Execute(changeRequest); AuditDetailCollection details = changeResponse.AuditDetailCollection; var attributeChangeHistoryResponse = (RetrieveAttributeChangeHistoryResponse)_service.Execute(attributeChangeHistoryRequest); details = attributeChangeHistoryResponse.AuditDetailCollection; foreach (var detail in details.AuditDetails) { //AuditHistory change = GetRecordChanges(detail); auditHistoryForRecord.AddRange(GetRecordChanges(detail, recordKeyValue)); //if (change != null) //{ // change.RecordKeyValue = recordKeyValue; // auditHistoryForRecord.Add(change); //} } return(auditHistoryForRecord); }
/// <summary> /// Loops thru the audit detail collections /// and builds a lift of audit data changes /// </summary> /// <param type="AuditDetailCollections" name="details"></param> /// <returns> Returns a List of AuditDataChanges </returns> private List <AuditDataChange> _ProcessAuditDetails(AuditDetailCollection details) { try { var auditExtractList = new List <AuditDataChange>(); foreach (var detail in details.AuditDetails) { var detailType = detail.GetType(); if (detailType == typeof(AttributeAuditDetail)) { var attributeDetail = (AttributeAuditDetail)detail; var attributeValue = attributeDetail.NewValue ?? attributeDetail.OldValue; var modifiedDateTime = (DateTime)detail.AuditRecord.Attributes["createdon"]; var user = ((EntityReference)detail.AuditRecord.Attributes["userid"]).Name.ToString(); if (attributeValue != null && attributeValue.Attributes != null) { foreach (var attribute in attributeValue.Attributes) { if (Util.AuditExportFields.Any(item => item.Equals(attribute.Key))) { var change = new AuditDataChange(); Object valueNew = null; Object valueOld = null; if (attributeDetail.NewValue != null) { valueNew = (attributeDetail.NewValue.Attributes.ContainsKey(attribute.Key)) ? attributeDetail.NewValue.Attributes[attribute.Key] : null; } if (attributeDetail.OldValue != null) { valueOld = (attributeDetail.OldValue.Attributes.ContainsKey(attribute.Key)) ? attributeDetail.OldValue.Attributes[attribute.Key] : null; } change.ActionType = detail.AuditRecord.FormattedValues["action"]; change.AttributeName = attribute.Key; change.AttributeNewValue = _ProcessAuditDetailBasedOnType(valueNew, attribute.Key); change.AttributeOldValue = _ProcessAuditDetailBasedOnType(valueOld, attribute.Key); change.ModifiedDate = modifiedDateTime.ToLocalTime(); change.ModifiedBy = user; auditExtractList.Add(change); } } } } } return(auditExtractList); } catch (Exception ex) { Util.WriteErrorToLog("_ProcessAuditDetails", new Dictionary <string, string>(), ex); throw ex; } }
public void retrieveAuditData() { IOrganizationService service = CRMHelper.ConnectToMSCRM(); // Retrieve the audit history for the account and display it. RetrieveRecordChangeHistoryRequest changeRequest = new RetrieveRecordChangeHistoryRequest(); changeRequest.Target = new EntityReference("account", new Guid("A9B96053-43B1-E111-A892-1CC1DEEAE7D7")); RetrieveRecordChangeHistoryResponse changeResponse = (RetrieveRecordChangeHistoryResponse)service.Execute(changeRequest); AuditDetailCollection details = changeResponse.AuditDetailCollection; }
private void RetrieveRecordChangeHistory() { this.LogMessage(LogType.Info, "Retrieveing for {0}", this.EntityId); // Retrieve the audit history for the account and display it. RetrieveRecordChangeHistoryRequest changeRequest = new RetrieveRecordChangeHistoryRequest(); changeRequest.Target = new EntityReference(this.EntityName, this.EntityId); RetrieveRecordChangeHistoryResponse changeResponse = (RetrieveRecordChangeHistoryResponse)this.OrgService.Execute(changeRequest); this.auditCollection = changeResponse.AuditDetailCollection; }
public List <AuditHistory> GetAuditHistoryForRecord(Guid entityID, string entityLogicalName, string recordKeyValue) { List <AuditHistory> auditHistoryForRecord = new List <AuditHistory>(); RetrieveRecordChangeHistoryRequest changeRequest = new RetrieveRecordChangeHistoryRequest(); changeRequest.Target = new EntityReference(entityLogicalName, entityID); RetrieveRecordChangeHistoryResponse changeResponse = (RetrieveRecordChangeHistoryResponse)_service.Execute(changeRequest); AuditDetailCollection details = changeResponse.AuditDetailCollection; foreach (AuditDetail detail in details.AuditDetails) { auditHistoryForRecord.AddRange(GetRecordChanges(detail, recordKeyValue)); } return(auditHistoryForRecord); }
public void It_Should_Retrieve_Old_Values_From_Audit() { var context = new XrmFakedContext(); var service = context.GetFakedOrganizationService(); var tracing = context.GetFakeTracingService(); var contact = new Entity { LogicalName = "contact", Id = Guid.NewGuid(), Attributes = new AttributeCollection { { "name", "newName" } } }; context.AddExecutionMock <RetrieveRecordChangeHistoryRequest>((OrganizationRequest req) => { var auditDetail = new AttributeAuditDetail { OldValue = new Entity { LogicalName = "contact", Id = Guid.NewGuid(), ["name"] = "oldName" } }; var collection = new AuditDetailCollection(); collection.AuditDetails.Add(auditDetail); return(new RetrieveRecordChangeHistoryResponse { Results = new ParameterCollection { { "AuditDetailCollection", collection } } }); }); var formula = "RetrieveAudit (PrimaryRecord(), \"name\")"; var result = new XTLInterpreter(formula, contact, null, service, tracing).Produce(); Assert.That(result, Is.EqualTo("oldName")); }
public List <AuditHistory> RetrieveRecordChangeHistory(EntityReference target) { AuditHistoryManager manager = new AuditHistoryManager(crmseviceClient); List <AuditHistory> auditHistoryForRecord = new List <AuditHistory>(); RetrieveRecordChangeHistoryRequest changeRequest = new RetrieveRecordChangeHistoryRequest(); changeRequest.Target = target; //new EntityReference("account", new Guid("b1f68180-4c5a-eb11-bb23-000d3a0a74cb")); RetrieveRecordChangeHistoryResponse changeResponse = (RetrieveRecordChangeHistoryResponse)crmseviceClient.Execute(changeRequest); AuditDetailCollection details = changeResponse.AuditDetailCollection; foreach (AuditDetail detail in details.AuditDetails) { List <AuditHistory> records = manager.GetRecordChanges(detail); auditHistoryForRecord.AddRange(records); } return(auditHistoryForRecord); }
public DateTime CheckLastLoginDate(IOrganizationService service, Guid systemUserId) { try { // Retrieve the audit history for the account and display it. RetrieveRecordChangeHistoryRequest changeRequest = new RetrieveRecordChangeHistoryRequest(); changeRequest.Target = new EntityReference("systemuser", systemUserId); RetrieveRecordChangeHistoryResponse changeResponse = (RetrieveRecordChangeHistoryResponse)service.Execute(changeRequest); AuditDetailCollection details = changeResponse.AuditDetailCollection; var auditRecords = details.AuditDetails; for (int i = 0; i < auditRecords.Count; i++) { // READ: https://docs.microsoft.com/en-us/dynamics365/customer-engagement/web-api/audit?view=dynamics-ce-odata-9#see-also // 64 = "User Access via Web" // 65 = "User Access via Web Services" var auditActionType = auditRecords[i].AuditRecord.GetAttributeValue <OptionSetValue>("action").Value; var auditCreatedOn = auditRecords[i].AuditRecord.GetAttributeValue <DateTime>("createdon").ToLocalTime(); if ((auditActionType == 64 || auditActionType == 65) && auditCreatedOn > DateTime.Today.AddMonths(-6)) { return(auditCreatedOn); } } return(new DateTime(1900, 01, 01)); // EVT: https://docs.microsoft.com/en-us/dynamics365/customerengagement/on-premises/developer/sample-disable-user } catch (Exception) { throw; } }
private void CaptureAuditDetails(AuditDetailCollection details, Microsoft.Office.Interop.Excel._Worksheet workSheet, string title) { string actionFilter = ((ComboBoxItem)AuditActionFilter.SelectedItem).Content.ToString(); foreach (var detail in details.AuditDetails) { // Write out some of the change history information in the audit record. var record = detail.AuditRecord; if (actionFilter == "All" || (actionFilter != "All" && actionFilter == record.FormattedValues["action"])) { var ExportExcelObj = new AddAuditRecordToExcel() { EntityName = record.LogicalName, Action = record.FormattedValues["action"], Operation = record.FormattedValues["operation"], CreatedOn = record.GetAttributeValue <DateTime>("createdon").ToLocalTime().ToString(), Attributes = new List <Attribute>() }; var detailType = detail.GetType(); if (detailType == typeof(AttributeAuditDetail)) { var attributeDetail = (AttributeAuditDetail)detail; // Display the old and new attribute values. if (attributeDetail.NewValue != null) { foreach (KeyValuePair <String, object> attribute in attributeDetail.NewValue.Attributes) { String oldValue = "(no value)", newValue = "(no value)"; var type = attribute.Value.GetType().ToString(); // Display the lookup values of those attributes that do not contain strings. if (attributeDetail.OldValue != null) { if (attributeDetail.OldValue.Contains(attribute.Key)) { switch (attribute.Value.GetType().ToString()) { case "Microsoft.Xrm.Sdk.OptionSetValue": oldValue = attributeDetail.OldValue.GetAttributeValue <OptionSetValue>(attribute.Key).Value.ToString(); break; case "Microsoft.Xrm.Sdk.EntityReference": var ref_ = attributeDetail.OldValue.GetAttributeValue <EntityReference>(attribute.Key); oldValue = ref_.Name + ", {" + ref_.Id + "}"; break; default: oldValue = attributeDetail.OldValue[attribute.Key].ToString(); break; } } } switch (attribute.Value.GetType().ToString()) { case "Microsoft.Xrm.Sdk.OptionSetValue": newValue = attributeDetail.NewValue.GetAttributeValue <OptionSetValue>(attribute.Key).Value.ToString(); break; case "Microsoft.Xrm.Sdk.EntityReference": var ref_ = attributeDetail.NewValue.GetAttributeValue <EntityReference>(attribute.Key); newValue = ref_.Name + ", {" + ref_.Id + "}"; break; default: newValue = attributeDetail.NewValue[attribute.Key].ToString(); break; } ExportExcelObj.Attributes.Add(new Attribute() { AttributeName = attribute.Key, OldValue = oldValue, NewValue = newValue }); } } if (attributeDetail.OldValue != null) { foreach (KeyValuePair <String, object> attribute in attributeDetail.OldValue.Attributes) { String oldValue = "(no value)"; switch (attribute.Value.GetType().ToString()) { case "Microsoft.Xrm.Sdk.OptionSetValue": oldValue = attributeDetail.OldValue.GetAttributeValue <OptionSetValue>(attribute.Key).Value.ToString(); break; case "Microsoft.Xrm.Sdk.EntityReference": var ref_ = attributeDetail.OldValue.GetAttributeValue <EntityReference>(attribute.Key); oldValue = ref_.Name + ", {" + ref_.Id + "}"; break; default: oldValue = attributeDetail.OldValue[attribute.Key].ToString(); break; } if (attributeDetail.NewValue != null) { if (!attributeDetail.NewValue.Contains(attribute.Key)) { ExportExcelObj.Attributes.Add(new Attribute() { AttributeName = attribute.Key, OldValue = oldValue, NewValue = "(no value)" }); } } else { ExportExcelObj.Attributes.Add(new Attribute() { AttributeName = attribute.Key, OldValue = oldValue, NewValue = "(no value)" }); } } } } rowCount = ExportExcelObj.ExportToExcel(workSheet, rowCount, title); } } }
/// <summary> /// This method first connects to the organization service. Afterwards, /// auditing is enabled on the organization, account entity, and a couple /// of attributes. Finally, display that information in Console, and creates /// an XML file. /// </summary> /// <param name="serverConfig">Contains server connection information.</param> /// <param name="promptforDelete">When True, the user will be prompted to delete all /// created entities.</param> public void Run(ServerConnection.Configuration serverConfig, bool promptforDelete) { _sampleStartTime = DateTime.Now; using (_serviceProxy = ServerConnection.GetOrganizationProxy(serverConfig)) { // This statement is required to enable early-bound type support. _serviceProxy.EnableProxyTypes(); // You can access the service through the proxy, but this sample uses the interface instead. _service = _serviceProxy; #region Enable Auditing for an Account Console.WriteLine("Enabling auditing on the organization and account entities."); // Enable auditing on the organization. // First, get the organization's ID from the system user record. Guid orgId = ((WhoAmIResponse)_service.Execute(new WhoAmIRequest())).OrganizationId; // Next, retrieve the organization's record. Organization org = _service.Retrieve(Organization.EntityLogicalName, orgId, new ColumnSet(new string[] { "organizationid", "isauditenabled" })) as Organization; // Finally, enable auditing on the organization. bool organizationAuditingFlag = org.IsAuditEnabled.Value; bool usersAccessAuditingFlag = org.IsUserAccessAuditEnabled.HasValue ? org.IsUserAccessAuditEnabled.Value : false; org.IsAuditEnabled = true; org.IsUserAccessAuditEnabled = true; _service.Update(org); // Enable auditing on account entities. bool accountAuditingFlag = EnableEntityAuditing(Account.EntityLogicalName, true); #endregion Enable Auditing for an Account CreateRequiredRecords(); #region Create and start XML file // Create the XML file String fileName = "auditReport.xml"; textWriter = new XmlTextWriter(fileName, null); textWriter.WriteStartDocument(); // Start Audit Node textWriter.WriteStartElement("auditReport", ""); #endregion #region Retrive user access audit records var query = new QueryExpression(Audit.EntityLogicalName) { ColumnSet = new ColumnSet("createdon", "action", "operation", "objectid"), Criteria = new FilterExpression(LogicalOperator.And) }; // Only retrieve audit records that track user access. query.Criteria.AddCondition("action", ConditionOperator.In, (int)AuditAction.UserAccessAuditStarted, (int)AuditAction.UserAccessAuditStopped, (int)AuditAction.UserAccessviaWebServices, (int)AuditAction.UserAccessviaWeb); // Change this to false in order to retrieve audit records for all users // when running the sample. var filterAuditsRetrievedByUser = true; if (filterAuditsRetrievedByUser) { // Only retrieve audit records for the current user. var userFilter = new FilterExpression(LogicalOperator.Or); userFilter.AddCondition( "userid", ConditionOperator.Equal, _serviceProxy.CallerId); } // Only retrieve records for this sample run, so that we don't get too // many results if auditing was enabled previously. query.Criteria.AddCondition( "createdon", ConditionOperator.GreaterEqual, _sampleStartTime); var results = _serviceProxy.RetrieveMultiple(query); foreach (Audit audit in results.Entities) { // Display results DisplayAndAddToXMLFileUserAccessDetails(audit); } #endregion #region Retrieve the Audit History Console.WriteLine("Retrieving the account change history.\n"); DateTime startTime = DateTime.Now; // Retrieve the audit records for accounts. RetrieveRecordChangeHistoryRequest changeRequest = new RetrieveRecordChangeHistoryRequest(); changeRequest.Target = new EntityReference(Account.EntityLogicalName, _newAccountId); RetrieveRecordChangeHistoryResponse changeResponse = (RetrieveRecordChangeHistoryResponse)_service.Execute(changeRequest); AuditDetailCollection details = changeResponse.AuditDetailCollection; foreach (AttributeAuditDetail detail in details.AuditDetails) { // Write out some of the information in each audit record. DisplayAndAddToXMLFileAuditDetails(detail); } #endregion Retrieve the Audit History #region RetrieveAttributeChangeHistoryRequest // How to use message: RetrieveAttributeChangeHistoryRequest // Update Telephone1 in account entity Account accountToUpdate = new Account(); accountToUpdate.AccountId = _newAccountId; accountToUpdate.Telephone1 = "123-555-5555"; _serviceProxy.Update(accountToUpdate); Console.WriteLine("Updated Telephone1 field in Account entity."); Console.WriteLine("Retrieving attribute change history for Telephone1."); // Create RetrieveAttributeChangeHistoryRequest var attributeChangeHistoryRequest = new RetrieveAttributeChangeHistoryRequest { Target = new EntityReference( Account.EntityLogicalName, _newAccountId), AttributeLogicalName = "telephone1" }; // Execute RetrieveAttributeChangeHistoryRequest var attributeChangeHistoryResponse = (RetrieveAttributeChangeHistoryResponse)_service.Execute(attributeChangeHistoryRequest); // Set AuditDetailCollection and output to console details = attributeChangeHistoryResponse.AuditDetailCollection; foreach (var detail in details.AuditDetails) { DisplayAndAddToXMLFileAuditDetails(detail); } // Create an Audit record // to store a sample for use with RetrieveAuditDetailsRequest Guid auditSampleId = details.AuditDetails.First().AuditRecord.Id; #endregion RetrieveAttributeChangeHistoryRequest #region RetrieveAuditDetailsRequest // How to use message: RetrieveAuditDetailsRequest Console.WriteLine("Retrieving audit details for an audit record."); // Create RetrieveAuditDetailsRequest var auditDetailsRequest = new RetrieveAuditDetailsRequest { AuditId = auditSampleId }; // Execute RetrieveAuditDetailsRequest var auditDetailsResponse = (RetrieveAuditDetailsResponse)_service.Execute(auditDetailsRequest); // Display results DisplayAndAddToXMLFileAuditDetails(auditDetailsResponse.AuditDetail); #endregion RetrieveAuditDetailsRequest #region Retrieve AuditExtension details Console.WriteLine("Simulating a user reading records"); _service.Retrieve(Account.EntityLogicalName, _newAccountId, new ColumnSet("accountid")); // creating read records is an async process - wait until the records have been created // wait a max of 30 seconds Console.WriteLine("Fetching read audit records for accounts"); for (int i = 0; i < 30; i++) { query = new QueryExpression { EntityName = "sample_auditextension", ColumnSet = new ColumnSet("createdon", "sample_objectlogicalname", "sample_objectid", "sample_userid", "sample_action", "sample_operation"), Criteria = new FilterExpression { Conditions = { new ConditionExpression("sample_objectlogicalname", ConditionOperator.Equal, Account.EntityLogicalName), new ConditionExpression("sample_objectid", ConditionOperator.Equal, _newAccountId.ToString().TrimStart('{').TrimEnd('}')) } } }; results = _service.RetrieveMultiple(query); if (results.Entities.Count > 0) { break; } else if (i == 29) { throw new Exception("Exceeded maximum wait time"); } System.Threading.Thread.Sleep(1000); } foreach (var record in results.Entities) { _auditExtensionRecordIds.Add(record.Id); DisplayAndAddToXmlFileAuditExtension(record); } #endregion #region Finish and close XML file // End auditReport Xml Node textWriter.WriteEndElement(); textWriter.WriteEndDocument(); // Close xml writer. textWriter.Close(); Console.WriteLine("File name: " + fileName); #endregion #region Revert auditing // Set the organization and account auditing flags back to the old values org.IsAuditEnabled = organizationAuditingFlag; org.IsUserAccessAuditEnabled = usersAccessAuditingFlag; _service.Update(org); EnableEntityAuditing(Account.EntityLogicalName, accountAuditingFlag); #endregion Revert auditing DeleteRequiredRecords(promptforDelete); } }
public async Task <string> retrieveAudit() { await setLabelAsync(totalRecCount, "Connecting to CRM"); string url = DynURL.Text; string userName = DynUserName.Text; string passwrd = DynPass.Password; if (ConnectionManager._service == null) { ConnectionManager.createCRMConnection(url, userName, passwrd); } var service = ConnectionManager._service; // Load Excel application excel = new Microsoft.Office.Interop.Excel.Application(); // Create empty workbook excel.Workbooks.Add(); // Create Worksheet from active sheet Microsoft.Office.Interop.Excel._Worksheet workSheet = excel.ActiveSheet; try { string fetchXml = FetchXml.Text; if (fetchXml != null) { await setLabelAsync(totalRecCount, "Querying..."); FetchExpression fetchExp = new FetchExpression(fetchXml); EntityCollection entColl = service.RetrieveMultiple(fetchExp); if (entColl.Entities.Count > 0) { await setLabelAsync(totalRecCount, entColl.Entities.Count.ToString()); await setLabelAsync(processRecCount, "Fetching Audit History..."); int index = 0; // Defining header cells workSheet.Cells[1, "A"] = "Title"; workSheet.Cells[1, "B"] = "Entity Name"; workSheet.Cells[1, "C"] = "Action"; workSheet.Cells[1, "D"] = "Operation"; workSheet.Cells[1, "E"] = "Audit Record Created On"; workSheet.Cells[1, "F"] = "Attribute Name"; workSheet.Cells[1, "G"] = "Old Value"; workSheet.Cells[1, "H"] = "New Value"; rowCount = 2; Dictionary <int, AuditDetailCollection> AuditDetailsFetched = new Dictionary <int, AuditDetailCollection>(); #region Execute Multiple with Results // Create an ExecuteMultipleRequest object. ExecuteMultipleRequest requestWithResults = new ExecuteMultipleRequest() { // Assign settings that define execution behavior: continue on error, return responses. Settings = new ExecuteMultipleSettings() { ContinueOnError = false, ReturnResponses = true }, // Create an empty organization request collection. Requests = new OrganizationRequestCollection() }; // Add a CreateRequest for each entity to the request collection. foreach (Entity ent in entColl.Entities) { RetrieveRecordChangeHistoryRequest changeHistoryRequest = new RetrieveRecordChangeHistoryRequest(); changeHistoryRequest.Target = ent.ToEntityReference(); requestWithResults.Requests.Add(changeHistoryRequest); } // Execute all the requests in the request collection using a single web method call. ExecuteMultipleResponse changeHistoryResponses = (ExecuteMultipleResponse)service.Execute(requestWithResults); // Display the results returned in the responses. foreach (var changeHistoryResponse in changeHistoryResponses.Responses) { // A valid response. if (changeHistoryResponse.Response != null) { AuditDetailCollection details = ((RetrieveRecordChangeHistoryResponse)(changeHistoryResponse.Response)).AuditDetailCollection; AuditDetailsFetched.Add(changeHistoryResponse.RequestIndex, details); } // An error has occurred. else if (changeHistoryResponse.Fault != null) { MessageBox.Show("Exception: There was a problem in extacting the Audit History. " + changeHistoryResponse.Fault.ToString()); } } #endregion foreach (KeyValuePair <int, AuditDetailCollection> auditItem in AuditDetailsFetched) { index++; if (index > 0) { await setLabelAsync(processRecCount, index.ToString()); var title = "Not Found"; var index_ = auditItem.Key; if (entColl.Entities[auditItem.Key].Attributes.ContainsKey(TitleAttribute.Text)) { title = entColl.Entities[auditItem.Key].GetAttributeValue <string>(TitleAttribute.Text); } CaptureAuditDetails(auditItem.Value, workSheet, title); } } // Apply some predefined styles for data to look nicely workSheet.Range["A1"].AutoFormat(Microsoft.Office.Interop.Excel.XlRangeAutoFormat.xlRangeAutoFormatClassic1); string fileName = ""; // Define filename if (DesktopDirCheck.IsChecked.Value) { fileName = string.Format(@"{0}\" + FileName.Text, Environment.GetFolderPath(Environment.SpecialFolder.DesktopDirectory)); } else if (SaveLocation.Text != "" && FileName.Text != null) { fileName = string.Format(@"{0}\" + FileName.Text, SaveLocation.Text); } // Save this data as a file if (fileName != "") { workSheet.SaveAs(fileName); } // Display SUCCESS message MessageBox.Show(string.Format("The file '{0}' is saved successfully!", fileName)); } else { MessageBox.Show("Connection Successful. No records retrieved."); } } } catch (Exception exception) { MessageBox.Show("Exception: There was a problem saving Excel file!\n" + exception.Message); } finally { // Quit Excel application excel.Quit(); // Release COM objects (very important!) if (excel != null) { System.Runtime.InteropServices.Marshal.ReleaseComObject(excel); } if (workSheet != null) { System.Runtime.InteropServices.Marshal.ReleaseComObject(workSheet); } // Empty variables excel = null; workSheet = null; // Force garbage collector cleaning GC.Collect(); } ConnectionManager._service = null; return("Success"); }
/// <summary> /// This method first connects to the organization service. Next, auditing /// is enabled on the organization and an account entity. The account record /// is updated and the audit history printed out. /// </summary> /// <param name="serverConfig">Contains server connection information.</param> /// <param name="promptforDelete">When True, the user will be prompted to delete all /// created entities.</param> public void Run(ServerConnection.Configuration serverConfig, bool promptforDelete) { using (_serviceProxy = ServerConnection.GetOrganizationProxy(serverConfig)) { // Enable early-bound type support. _serviceProxy.EnableProxyTypes(); // You can access the service through the proxy, but this sample uses the interface instead. _service = _serviceProxy; #region Enable Auditing for an Account //<snippetAuditing1> Console.WriteLine("Enabling auditing on the organization and account entities."); // Enable auditing on the organization. // First, get the organization's ID from the system user record. Guid orgId = ((WhoAmIResponse)_service.Execute(new WhoAmIRequest())).OrganizationId; // Next, retrieve the organization's record. Organization org = _service.Retrieve(Organization.EntityLogicalName, orgId, new ColumnSet(new string[] { "organizationid", "isauditenabled" })) as Organization; // Finally, enable auditing on the organization. bool organizationAuditingFlag = org.IsAuditEnabled.Value; org.IsAuditEnabled = true; _service.Update(org); // Enable auditing on account entities. bool accountAuditingFlag = EnableEntityAuditing(Account.EntityLogicalName, true); //</snippetAuditing1> #endregion Enable Auditing for an Account CreateRequiredRecords(); #region Retrieve the Record Change History Console.WriteLine("Retrieving the account change history.\n"); //<snippetAuditing5> // Retrieve the audit history for the account and display it. RetrieveRecordChangeHistoryRequest changeRequest = new RetrieveRecordChangeHistoryRequest(); changeRequest.Target = new EntityReference(Account.EntityLogicalName, _newAccountId); RetrieveRecordChangeHistoryResponse changeResponse = (RetrieveRecordChangeHistoryResponse)_service.Execute(changeRequest); AuditDetailCollection details = changeResponse.AuditDetailCollection; //</snippetAuditing5> foreach (AttributeAuditDetail detail in details.AuditDetails) { // Display some of the detail information in each audit record. DisplayAuditDetails(detail); } #endregion Retrieve the Record Change History #region Retrieve the Attribute Change History //<snippetAuditing7> // Update the Telephone1 attribute in the Account entity record. Account accountToUpdate = new Account(); accountToUpdate.AccountId = _newAccountId; accountToUpdate.Telephone1 = "123-555-5555"; _serviceProxy.Update(accountToUpdate); Console.WriteLine("Updated the Telephone1 field in the Account entity."); // Retrieve the attribute change history. Console.WriteLine("Retrieving the attribute change history for Telephone1."); var attributeChangeHistoryRequest = new RetrieveAttributeChangeHistoryRequest { Target = new EntityReference( Account.EntityLogicalName, _newAccountId), AttributeLogicalName = "telephone1" }; var attributeChangeHistoryResponse = (RetrieveAttributeChangeHistoryResponse)_service.Execute(attributeChangeHistoryRequest); // Display the attribute change history. details = attributeChangeHistoryResponse.AuditDetailCollection; //</snippetAuditing7> foreach (var detail in details.AuditDetails) { DisplayAuditDetails(detail); } // Save an Audit record ID for later use. Guid auditSampleId = details.AuditDetails.First().AuditRecord.Id; #endregion Retrieve the Attribute Change History #region Retrieve the Audit Details //<snippetAuditing8> Console.WriteLine("Retrieving audit details for an audit record."); // Retrieve the audit details and display them. var auditDetailsRequest = new RetrieveAuditDetailsRequest { AuditId = auditSampleId }; var auditDetailsResponse = (RetrieveAuditDetailsResponse)_service.Execute(auditDetailsRequest); //</snippetAuditing8> DisplayAuditDetails(auditDetailsResponse.AuditDetail); #endregion Retrieve the Audit Details #region Revert Auditing // Set the organization and account auditing flags back to the old values org.IsAuditEnabled = organizationAuditingFlag; _service.Update(org); EnableEntityAuditing(Account.EntityLogicalName, accountAuditingFlag); #endregion Revert Auditing DeleteRequiredRecords(promptforDelete); } }
/// <summary> /// Loops thru the audit detail collections /// and builds a lift of audit data changes /// </summary> /// <param type="AuditDetailCollections" name="details"></param> /// <returns> Returns a List of AuditDataChanges </returns> private List<AuditDataChange> _ProcessAuditDetails(AuditDetailCollection details) { try { var auditExtractList = new List<AuditDataChange>(); foreach (var detail in details.AuditDetails) { var detailType = detail.GetType(); if (detailType == typeof(AttributeAuditDetail)) { var attributeDetail = (AttributeAuditDetail)detail; var attributeValue = attributeDetail.NewValue ?? attributeDetail.OldValue; var modifiedDateTime = (DateTime)detail.AuditRecord.Attributes["createdon"]; var user = ((EntityReference)detail.AuditRecord.Attributes["userid"]).Name.ToString(); if (attributeValue != null && attributeValue.Attributes != null) { foreach (var attribute in attributeValue.Attributes) { if (Util.AuditExportFields.Any(item => item.Equals(attribute.Key))) { var change = new AuditDataChange(); Object valueNew = null; Object valueOld = null; if (attributeDetail.NewValue != null) { valueNew = (attributeDetail.NewValue.Attributes.ContainsKey(attribute.Key)) ? attributeDetail.NewValue.Attributes[attribute.Key] : null; } if (attributeDetail.OldValue != null) { valueOld = (attributeDetail.OldValue.Attributes.ContainsKey(attribute.Key)) ? attributeDetail.OldValue.Attributes[attribute.Key] : null; } change.ActionType = detail.AuditRecord.FormattedValues["action"]; change.AttributeName = attribute.Key; change.AttributeNewValue = _ProcessAuditDetailBasedOnType(valueNew, attribute.Key); change.AttributeOldValue = _ProcessAuditDetailBasedOnType(valueOld, attribute.Key); change.ModifiedDate = modifiedDateTime.ToLocalTime(); change.ModifiedBy = user; auditExtractList.Add(change); } } } } } return auditExtractList; } catch (Exception ex) { Util.WriteErrorToLog("_ProcessAuditDetails", new Dictionary<string, string>(), ex); throw ex; } }
static void Main(string[] args) { //OrganizationServiceProxy serviceProxy = ConnectHelper.CrmService; //var service = (IOrganizationService)serviceProxy; //serviceProxy.ServiceConfiguration.CurrentServiceEndpoint.Behaviors.Add(new ProxyTypesBehavior()); IOrganizationService organizationService = null; try { ClientCredentials clientCredentials = new ClientCredentials(); clientCredentials.UserName.UserName = "******"; clientCredentials.UserName.Password = "******"; organizationService = (IOrganizationService) new OrganizationServiceProxy(new Uri("https://udstrialsdemo40.api.crm4.dynamics.com/XRMServices/2011/Organization.svc"), null, clientCredentials, null); RetrieveRecordChangeHistoryRequest changeRequest = new RetrieveRecordChangeHistoryRequest(); changeRequest.Target = new EntityReference("account", new Guid("{B0B2DD8A-F30D-EB11-A813-000D3A666701}")); RetrieveRecordChangeHistoryResponse changeResponse = (RetrieveRecordChangeHistoryResponse)organizationService.Execute(changeRequest); AuditDetailCollection details = changeResponse.AuditDetailCollection; } catch (Exception ex) { Console.WriteLine(ex.Message); } #region Task14Testing // TempRepository tempRepository = new TempRepository(service); // var vo = tempRepository.GetVoMainScriptRecors().Entities; // foreach (var item in vo) // { // Console.WriteLine(item.Id+" "+item.Attributes["new_name"]); // } // var entity = vo[0]; // var name = entity.LogicalName; // var id = entity.Id; // string path = @"D:\C# Junior собеседование\UDS Consulting (стажировка)\Developer Education\ЛК1.docx"; // string fileAsString = GetBase64StringFromFile(path); // string fileName = Path.GetFileName(path); // string mimeType = MimeMapping.GetMimeMapping(fileName); // Entity Note = new Entity("annotation"); // Note["objectid"] = new EntityReference(name, id); // Note["objecttypecode"] = name; // Note["subject"] = "Test Subject"; // Note["notetext"] = "Test note text"; // Note["documentbody"] = fileAsString; // Note["mimetype"] = mimeType; // Note["filename"] = fileName; // service.Create(Note); #endregion Console.ReadLine(); }
private void LoadAuditHistoryLogic() { if (Service != null) { RetrieveRecordChangeHistoryRequest changeRequest = new RetrieveRecordChangeHistoryRequest(); try { Guid guid = TrimGuid(recordGuid.Text); changeRequest.Target = new EntityReference(entitiesList.SelectedItem.ToString(), guid); RetrieveRecordChangeHistoryResponse changeResponse = (RetrieveRecordChangeHistoryResponse)Service.Execute(changeRequest); AuditDetailCollection auditDetailCollection = changeResponse.AuditDetailCollection; Entity entity = Service.Retrieve(entitiesList.SelectedItem.ToString(), guid, new ColumnSet(true)); TargetEntity = new Entity(entity.LogicalName, entity.Id); foreach (var attrAuditDetail in auditDetailCollection.AuditDetails) { var detailType = attrAuditDetail.GetType(); if (detailType == typeof(AttributeAuditDetail)) { var auditRecord = attrAuditDetail.AuditRecord; var attributeDetail = (AttributeAuditDetail)attrAuditDetail; var newValueEntity = attributeDetail.NewValue; var oldValueEntity = attributeDetail.OldValue; var action = auditRecord.FormattedValues["action"]; if (Array.Exists(ValidActions, x => x == action)) { foreach (KeyValuePair <String, object> attribute in attributeDetail.NewValue.Attributes) { string fieldmetadata = ""; string lookupId = ""; string oldValue = ""; string newValue = ""; if (attributeDetail.OldValue.Contains(attribute.Key)) { lookupId = GetLookupId(attribute.Key, attribute.Value, oldValueEntity, attribute.Key); fieldmetadata = GetFieldMetaData(attribute.Key, attribute.Value, oldValueEntity, attribute.Key); oldValue = GetFieldValue(attribute.Key, attribute.Value, oldValueEntity, oldValueEntity[attribute.Key].ToString()); } newValue = GetFieldValue(attribute.Key, attribute.Value, newValueEntity, newValueEntity[attribute.Key].ToString()); CreateAuditRecord(auditRecord.Attributes["auditid"], auditRecord.Attributes["createdon"], ((EntityReference)auditRecord.Attributes["userid"]).Name, auditRecord.FormattedValues["action"], attribute.Key, oldValue, newValue, attribute.Value, fieldmetadata, lookupId); } foreach (KeyValuePair <String, object> attribute in attributeDetail.OldValue.Attributes) { if (!attributeDetail.NewValue.Contains(attribute.Key)) { string fieldmetadata = ""; string loookupId = ""; string newValue = ""; loookupId = GetLookupId(attribute.Key, attribute.Value, oldValueEntity, attribute.Key); fieldmetadata = GetFieldMetaData(attribute.Key, attribute.Value, oldValueEntity, attribute.Key); string oldValue = GetFieldValue(attribute.Key, attribute.Value, oldValueEntity, oldValueEntity[attribute.Key].ToString()); CreateAuditRecord(auditRecord.Attributes["auditid"], auditRecord.Attributes["createdon"], ((EntityReference)auditRecord.Attributes["userid"]).Name, auditRecord.FormattedValues["action"], attribute.Key, oldValue, newValue, attribute.Value, fieldmetadata, loookupId); } } } } } } catch (InvalidPluginExecutionException ex) { MessageBox.Show($"An error occurred: {ex.Message}"); } catch (FaultException <OrganizationServiceFault> ex) { MessageBox.Show($"An error occurred: {ex.Message}"); } catch (TimeoutException ex) { MessageBox.Show($"An error occurred: {ex.Message}"); } catch (Exception ex) { MessageBox.Show($"An error occurred: {ex.Message}"); } } }
[STAThread] // Added to support UX static void Main(string[] args) { CrmServiceClient service = null; try { service = SampleHelpers.Connect("Connect"); if (service.IsReady) { #region Sample Code #region Set up SetUpSample(service); #endregion Set up #region Demonstrate Console.WriteLine("Enabling auditing on the organization and account entities."); // Enable auditing on the organization. // First, get the organization's ID from the system user record. Guid orgId = ((WhoAmIResponse)service.Execute(new WhoAmIRequest())).OrganizationId; // Next, retrieve the organization's record. var org = service.Retrieve(Organization.EntityLogicalName, orgId, new ColumnSet(new string[] { "organizationid", "isauditenabled" })) as Organization; // Finally, enable auditing on the organization. bool organizationAuditingFlag = org.IsAuditEnabled.Value; org.IsAuditEnabled = true; service.Update(org); // Enable auditing on account entities. bool accountAuditingFlag = EnableEntityAuditing(service, Account.EntityLogicalName, true); #endregion Enable Auditing for an Account #region Retrieve the Record Change History Console.WriteLine("Retrieving the account change history.\n"); // Retrieve the audit history for the account and display it. var changeRequest = new RetrieveRecordChangeHistoryRequest(); changeRequest.Target = new EntityReference(Account.EntityLogicalName, _newAccountId); var changeResponse = (RetrieveRecordChangeHistoryResponse)service.Execute(changeRequest); AuditDetailCollection details = changeResponse.AuditDetailCollection; foreach (AttributeAuditDetail detail in details.AuditDetails) { // Display some of the detail information in each audit record. DisplayAuditDetails(service, detail); } #endregion Retrieve the Record Change History #region Retrieve the Attribute Change History // Update the Telephone1 attribute in the Account entity record. var accountToUpdate = new Account(); accountToUpdate.AccountId = _newAccountId; accountToUpdate.Telephone1 = "123-555-5555"; service.Update(accountToUpdate); Console.WriteLine("Updated the Telephone1 field in the Account entity."); // Retrieve the attribute change history. Console.WriteLine("Retrieving the attribute change history for Telephone1."); var attributeChangeHistoryRequest = new RetrieveAttributeChangeHistoryRequest { Target = new EntityReference( Account.EntityLogicalName, _newAccountId), AttributeLogicalName = "telephone1" }; var attributeChangeHistoryResponse = (RetrieveAttributeChangeHistoryResponse)service.Execute(attributeChangeHistoryRequest); // Display the attribute change history. details = attributeChangeHistoryResponse.AuditDetailCollection; foreach (var detail in details.AuditDetails) { DisplayAuditDetails(service, detail); } // Save an Audit record ID for later use. Guid auditSampleId = details.AuditDetails.First().AuditRecord.Id; #endregion Retrieve the Attribute Change History #region Retrieve the Audit Details Console.WriteLine("Retrieving audit details for an audit record."); // Retrieve the audit details and display them. var auditDetailsRequest = new RetrieveAuditDetailsRequest { AuditId = auditSampleId }; var auditDetailsResponse = (RetrieveAuditDetailsResponse)service.Execute(auditDetailsRequest); DisplayAuditDetails(service, auditDetailsResponse.AuditDetail); #endregion Retrieve the Audit Details #region Revert Auditing // Set the organization and account auditing flags back to the old values org.IsAuditEnabled = organizationAuditingFlag; service.Update(org); EnableEntityAuditing(service, Account.EntityLogicalName, accountAuditingFlag); #endregion Revert Auditing #region Clean up CleanUpSample(service); #endregion Clean up } #endregion Demonstrate else { const string UNABLE_TO_LOGIN_ERROR = "Unable to Login to Dynamics CRM"; if (service.LastCrmError.Equals(UNABLE_TO_LOGIN_ERROR)) { Console.WriteLine("Check the connection string values in cds/App.config."); throw new Exception(service.LastCrmError); } else { throw service.LastCrmException; } } } catch (Exception ex) { SampleHelpers.HandleException(ex); } finally { if (service != null) { service.Dispose(); } Console.WriteLine("Press <Enter> to exit."); Console.ReadLine(); } }
/// <summary> /// Exports the entity. /// </summary> /// <param name="profile">The profile.</param> /// <param name="fetchXml">The fetch XML query.</param> /// <param name="PrimaryNameAttribute">The primary name attribute.</param> /// <param name="columns">The columns.</param> /// <param name="DisplayedColumns">The displayed columns.</param> /// <param name="sae">The sae.</param> /// <returns>The number of exported records</returns> public int ExportEntity(MSCRMAuditExportProfile profile, string fetchXml, string PrimaryNameAttribute, List<string> columns, List<string> DisplayedColumns, SelectedAuditEntity sae) { //Set the number of records per page to retrieve. //This value should not be bigger than 5000 as this is the limit of records provided by the CRM int fetchCount = 5000; // Initialize the file number. int fileNumber = 1; // Initialize the number of records. int recordCount = 0; // Specify the current paging cookie. For retrieving the first page, pagingCookie should be null. string pagingCookie = null; string entityName = ""; while (true) { // Build fetchXml string with the placeholders. string xml = CreateXml(fetchXml, pagingCookie, fileNumber, fetchCount); RetrieveMultipleRequest fetchRequest = new RetrieveMultipleRequest { Query = new FetchExpression(xml) }; EntityCollection returnCollection = ((RetrieveMultipleResponse)_serviceProxy.Execute(fetchRequest)).EntityCollection; recordCount += returnCollection.Entities.Count; if (recordCount > 0) { if (profile.AuditType == "User Acces Audit" || profile.AuditType == "Audit Summary View") { if (profile.ExportFormat.ToLower() == "csv") WriteCSV(returnCollection, fileName, columns, DisplayedColumns); else if (profile.ExportFormat.ToLower() == "xml") WriteXML(returnCollection, fileName, columns, DisplayedColumns); else if (profile.ExportFormat.ToLower() == "xml spreadsheet 2003") WriteXMLSpreadsheet2003(returnCollection, fileName, columns, DisplayedColumns); } else { foreach (Entity e in returnCollection.Entities) { AuditDetailCollection details = new AuditDetailCollection(); if (profile.AuditType == "Record Change History") { RetrieveRecordChangeHistoryRequest changeRequest = new RetrieveRecordChangeHistoryRequest(); changeRequest.Target = new EntityReference(returnCollection.EntityName, e.Id); RetrieveRecordChangeHistoryResponse changeResponse = (RetrieveRecordChangeHistoryResponse)_serviceProxy.Execute(changeRequest); details = changeResponse.AuditDetailCollection; } else { //Attribute change history var attributeChangeHistoryRequest = new RetrieveAttributeChangeHistoryRequest { Target = new EntityReference(e.LogicalName, e.Id), AttributeLogicalName = sae.SelectedAttributes[0] }; var attributeChangeHistoryResponse = (RetrieveAttributeChangeHistoryResponse)_serviceProxy.Execute(attributeChangeHistoryRequest); details = attributeChangeHistoryResponse.AuditDetailCollection; } foreach (AuditDetail detail in details.AuditDetails) { DisplayAuditDetails(detail, profile, (string)e[PrimaryNameAttribute], fileName, columns, DisplayedColumns); } } } } // Check for more records, if it returns 1. if (returnCollection.MoreRecords) { // Increment the page number to retrieve the next page. fileNumber++; pagingCookie = returnCollection.PagingCookie; } else { // If no more records in the result nodes, exit the loop. break; } } if (profile.ExportFormat.ToLower() == "xml" && File.Exists(fileName)) { using (var writer = new StreamWriter(fileName, true, encoding)) { writer.WriteLine("</Records>"); writer.Flush(); } } else if (profile.ExportFormat.ToLower() == "xml spreadsheet 2003" && File.Exists(fileName)) { using (var writer = new StreamWriter(fileName, true, encoding)) { writer.WriteLine("</Table></Worksheet></Workbook>\n"); writer.Flush(); } } LogManager.WriteLog("Exported " + recordCount + " " + entityName + " records."); return recordCount; }