1. 程式人生 > >自定義控制檯程式匯出角色對實體的許可權為Excel檔案

自定義控制檯程式匯出角色對實體的許可權為Excel檔案

本人微信公眾號:微軟動態CRM專家羅勇 ,回覆282或者20181116可方便獲取本文,同時可以在第一間得到我釋出的最新博文資訊,follow me!我的網站是 www.luoyong.me 。

先上圖讓大家看效果。許可權列沒有值則代表沒有授予這個許可權,1為個人級別,2為業務部門級別,3為上:下級業務部門,4為組織級別。

 

然後上程式碼,程式碼比較通俗易懂,有注意的地方我紅色標註了一下,自己可以加上一些篩選,比如去掉匯出對大部分標準實體的許可權等,當然這個程式並沒有匯出雜項許可權,有興趣的可以自己修改下。

  1 using Microsoft.Crm.Sdk.Messages;
2 using Microsoft.Xrm.Sdk; 3 using Microsoft.Xrm.Sdk.Client; 4 using Microsoft.Xrm.Sdk.Messages; 5 using Microsoft.Xrm.Sdk.Metadata; 6 using Microsoft.Xrm.Sdk.Query; 7 using System; 8 using System.Collections.Generic; 9 using System.Configuration; 10 using System.Linq; 11 using System.ServiceModel.Description;
12 using Excel = Microsoft.Office.Interop.Excel; 13 14 namespace ExportRolePrivileges 15 { 16 class lyPrivilege 17 { 18 public string EntitySchemaName; 19 public string EntityDisplayName; 20 public string CreatePrivilege; 21 public string ReadPrivilege;
22 public string WritePrivilege; 23 public string DeletePrivilege; 24 public string AppendPrivilege; 25 public string AppendToPrivilege; 26 public string AssignPrivilege; 27 public string SharePrivilege; 28 } 29 class Program 30 { 31 static void Main(string[] args) 32 { 33 IServiceManagement<IOrganizationService> orgServiceMgr = ServiceConfigurationFactory.CreateManagement<IOrganizationService>(new Uri(ConfigurationManager.AppSettings["orgUrl"])); 34 AuthenticationCredentials orgAuCredentials = new AuthenticationCredentials(); 35 orgAuCredentials.ClientCredentials.UserName.UserName = ConfigurationManager.AppSettings["userName"]; 36 orgAuCredentials.ClientCredentials.UserName.Password = ConfigurationManager.AppSettings["passWord"]; 37 using (OrganizationServiceProxy orgSvc = GetProxy<IOrganizationService, OrganizationServiceProxy>(orgServiceMgr, orgAuCredentials)) 38 { 39 WhoAmIRequest whoReq = new WhoAmIRequest(); 40 WhoAmIResponse whoRep = orgSvc.Execute(whoReq) as WhoAmIResponse; 41 var userEntity = orgSvc.Retrieve("systemuser", whoRep.UserId, new ColumnSet("fullname")); 42 Console.WriteLine(string.Format("登入組織{0}成功,歡迎{1},繼續操作請輸入y!", ConfigurationManager.AppSettings["orgUrl"], userEntity.GetAttributeValue<string>("fullname"))); 43 var input = Console.ReadLine().ToString().ToUpper(); 44 if (input == "Y") 45 { 46 Console.WriteLine(string.Format("程式開始處理 - {0}", DateTime.Now.ToString())); 47 var meta = GetEntityMetadata(orgSvc); 48 var excelApp = new Excel.Application(); 49 excelApp.Visible = false; 50 Excel.Workbook rolePrivilegeWorkbook = excelApp.Workbooks.Add(); 51 52 var roleList = GetRoleList(orgSvc); 53 Console.WriteLine(string.Format("共有{0}個角色 - {1}", roleList.Count, DateTime.Now.ToString())); 54 foreach (var role in roleList) 55 { 56 Excel.Worksheet activeWorksheet = rolePrivilegeWorkbook.Worksheets.Add(); 57 activeWorksheet.Name = role.Value; 58 int row = 1; 59 activeWorksheet.Cells[1, 1] = "實體架構名稱"; 60 activeWorksheet.Cells[1, 2] = "實體顯示名稱(中文)"; 61 activeWorksheet.Cells[1, 3] = "建立許可權"; 62 activeWorksheet.Cells[1, 4] = "讀許可權"; 63 activeWorksheet.Cells[1, 5] = "寫許可權"; 64 activeWorksheet.Cells[1, 6] = "刪除許可權"; 65 activeWorksheet.Cells[1, 7] = "追加許可權"; 66 activeWorksheet.Cells[1, 8] = "追加到許可權"; 67 activeWorksheet.Cells[1, 9] = "分派許可權"; 68 activeWorksheet.Cells[1, 10] = "共享許可權"; 69 activeWorksheet.Rows[1].Font.Bold = true;//字型加粗 70 row++; 71 var ls = GetRolePrivileges(orgSvc, role.Key, role.Value, meta).OrderBy(t => t.EntityDisplayName); 72 foreach (var item in ls) 73 { 74 activeWorksheet.Cells[row, 1] = item.EntitySchemaName; 75 activeWorksheet.Cells[row, 2] = item.EntityDisplayName; 76 activeWorksheet.Cells[row, 3] = item.CreatePrivilege; 77 activeWorksheet.Cells[row, 4] = item.ReadPrivilege; 78 activeWorksheet.Cells[row, 5] = item.WritePrivilege; 79 activeWorksheet.Cells[row, 6] = item.DeletePrivilege; 80 activeWorksheet.Cells[row, 7] = item.AppendPrivilege; 81 activeWorksheet.Cells[row, 8] = item.AppendToPrivilege; 82 activeWorksheet.Cells[row, 9] = item.AssignPrivilege; 83 activeWorksheet.Cells[row, 10] = item.SharePrivilege; 84 row++; 85 } 86 activeWorksheet.Columns[1].AutoFit();//自動列寬 87 activeWorksheet.Columns[2].AutoFit();//自動列寬 88 activeWorksheet.Columns[3].AutoFit();//自動列寬 89 activeWorksheet.Columns[4].AutoFit();//自動列寬 90 activeWorksheet.Columns[5].AutoFit();//自動列寬 91 activeWorksheet.Columns[6].AutoFit();//自動列寬 92 activeWorksheet.Columns[7].AutoFit();//自動列寬 93 activeWorksheet.Columns[8].AutoFit();//自動列寬 94 activeWorksheet.Columns[9].AutoFit();//自動列寬 95 activeWorksheet.Columns[10].AutoFit();//自動列寬 96 Console.WriteLine(string.Format("角色{0}處理完畢 - {1}", role.Value, DateTime.Now.ToString())); 97 } 98 rolePrivilegeWorkbook.SaveAs(Filename: @"D:\SecurityRolePrivileges.xlsx", FileFormat: Excel.XlFileFormat.xlWorkbookDefault); 99 rolePrivilegeWorkbook.Close(); 100 excelApp.Quit(); 101 } 102 } 103 Console.Write("程式執行完畢!"); 104 Console.ReadKey(); 105 } 106 107 private static TProxy GetProxy<TService, TProxy>( 108 IServiceManagement<TService> serviceManagement, 109 AuthenticationCredentials authCredentials) 110 where TService : class 111 where TProxy : ServiceProxy<TService> 112 { 113 Type classType = typeof(TProxy); 114 115 if (serviceManagement.AuthenticationType != 116 AuthenticationProviderType.ActiveDirectory) 117 { 118 AuthenticationCredentials tokenCredentials = 119 serviceManagement.Authenticate(authCredentials); 120 return (TProxy)classType 121 .GetConstructor(new Type[] { typeof(IServiceManagement<TService>), typeof(SecurityTokenResponse) }) 122 .Invoke(new object[] { serviceManagement, tokenCredentials.SecurityTokenResponse }); 123 } 124 return (TProxy)classType 125 .GetConstructor(new Type[] { typeof(IServiceManagement<TService>), typeof(ClientCredentials) }) 126 .Invoke(new object[] { serviceManagement, authCredentials.ClientCredentials }); 127 } 128 129 /// <summary> 130 /// 獲得角色列表,這裡排除了一部分角色 131 /// </summary> 132 /// <param name="orgSvc"></param> 133 /// <returns></returns> 134 private static Dictionary<Guid, string> GetRoleList(OrganizationServiceProxy orgSvc) 135 { 136 Dictionary<Guid, string> returnVal = new Dictionary<Guid, string>(); 137 string[] excludeRoles = new string[] { "Support User", "Delegate","System Administrator","Activity Feeds", 138 "Scheduler","System Customizer","Knowledge Manager","UIIAgent","UIIAdministrator","USD Administrator","USD Agent"}; 139 var rootBuId = GetRootBUId(orgSvc); 140 string fetchXml = string.Format(@"<fetch version='1.0' no-lock='true' mapping='logical' distinct='false'> 141 <entity name='role'> 142 <attribute name='name' /> 143 <attribute name='roleid' /> 144 <filter type='and'> 145 <condition attribute='businessunitid' operator='eq' value='{0}' /> 146 </filter> 147 </entity> 148 </fetch>", rootBuId); 149 foreach (var item in orgSvc.RetrieveMultiple(new FetchExpression(fetchXml)).Entities) 150 { 151 var roleName = item.GetAttributeValue<string>("name"); 152 if (!excludeRoles.Contains(roleName)) 153 { 154 returnVal.Add(item.GetAttributeValue<Guid>("roleid"), roleName); 155 } 156 } 157 return returnVal; 158 } 159 160 private static List<lyPrivilege> GetRolePrivileges(OrganizationServiceProxy orgSvc, Guid roleId, string roleName, Dictionary<string, string> entityMetadata) 161 { 162 Console.WriteLine(string.Format("開始提取角色 {0} - {1} 的許可權", roleName, roleId)); 163 List<lyPrivilege> temList = new List<lyPrivilege>(); 164 List<lyPrivilege> returnVal = new List<lyPrivilege>(); 165 string fetchXml = string.Format(@"<fetch version='1.0' mapping='logical' distinct='false' no-lock='true'> 166 <entity name='roleprivileges'> 167 <attribute name='privilegedepthmask'/> 168 <filter type='and'> 169 <condition attribute='roleid' operator='eq' value='{0}' /> 170 </filter> 171 <link-entity name='privilege' alias='prvs' to='privilegeid' from='privilegeid' link-type='inner'> 172 <attribute name='name'/> 173 <attribute name='accessright'/> 174 </link-entity> 175 </entity> 176 </fetch>", roleId); 177 foreach (var item in orgSvc.RetrieveMultiple(new FetchExpression(fetchXml)).Entities) 178 { 179 lyPrivilege lyp = new lyPrivilege(); 180 string prvName = item.GetAttributeValue<AliasedValue>("prvs.name").Value.ToString(); 181 lyp.EntitySchemaName = GetEntitySchemaName(prvName); 182 lyp.EntityDisplayName = GetEntityDisplayName(lyp.EntitySchemaName, entityMetadata); 183 int accessRight = Convert.ToInt32(item.GetAttributeValue<AliasedValue>("prvs.accessright").Value); 184 //可以根據需要排除對一些實體的許可權匯出來,做到更加簡潔 185 if (lyp.EntityDisplayName != string.Empty)//為空的不是實體許可權不需要處理 186 { 187 switch (accessRight) 188 { 189 case 1: 190 lyp.ReadPrivilege = TransferPrivilege(item.GetAttributeValue<int>("privilegedepthmask")).ToString(); 191 break; 192 case 2: 193 lyp.WritePrivilege = TransferPrivilege(item.GetAttributeValue<int>("privilegedepthmask")).ToString(); 194 break; 195 case 4: 196 lyp.AppendPrivilege = TransferPrivilege(item.GetAttributeValue<int>("privilegedepthmask")).ToString(); 197 break; 198 case 16: 199 lyp.AppendToPrivilege = TransferPrivilege(item.GetAttributeValue<int>("privilegedepthmask")).ToString(); 200 break; 201 case 32: 202 lyp.CreatePrivilege = TransferPrivilege(item.GetAttributeValue<int>("privilegedepthmask")).ToString(); 203 break; 204 case 65536: 205 lyp.DeletePrivilege = TransferPrivilege(item.GetAttributeValue<int>("privilegedepthmask")).ToString(); 206 break; 207 case 262144: 208 lyp.SharePrivilege = TransferPrivilege(item.GetAttributeValue<int>("privilegedepthmask")).ToString(); 209 break; 210 case 524288: 211 lyp.AssignPrivilege = TransferPrivilege(item.GetAttributeValue<int>("privilegedepthmask")).ToString(); 212 break; 213 } 214 temList.Add(lyp); 215 } 216 } 217 var distinctQuery = temList.GroupBy(p => new { p.EntitySchemaName }).Select(g => g.First()).ToList(); 218 foreach (var item in distinctQuery) 219 { 220 lyPrivilege prv = new lyPrivilege(); 221 prv.EntitySchemaName = item.EntitySchemaName; 222 prv.EntityDisplayName = item.EntityDisplayName; 223 prv.ReadPrivilege = temList.Where(t => t.EntitySchemaName == prv.EntitySchemaName && (!string.IsNullOrEmpty(t.ReadPrivilege))).Count() >= 1 ? temList.Where(t => t.EntitySchemaName == prv.EntitySchemaName && !string.IsNullOrEmpty(t.ReadPrivilege)).First().ReadPrivilege : string.Empty; 224 prv.WritePrivilege = temList.Where(t => t.EntitySchemaName == prv.EntitySchemaName && (!string.IsNullOrEmpty(t.WritePrivilege))).Count() >= 1 ? temList.Where(t => t.EntitySchemaName == prv.EntitySchemaName && !string.IsNullOrEmpty(t.WritePrivilege)).First().WritePrivilege : string.Empty; 225 prv.CreatePrivilege = temList.Where(t => t.EntitySchemaName == prv.EntitySchemaName && (!string.IsNullOrEmpty(t.CreatePrivilege))).Count() >= 1 ? temList.Where(t => t.EntitySchemaName == prv.EntitySchemaName && !string.IsNullOrEmpty(t.CreatePrivilege)).First().CreatePrivilege : string.Empty; 226 prv.AssignPrivilege = temList.Where(t => t.EntitySchemaName == prv.EntitySchemaName && (!string.IsNullOrEmpty(t.AssignPrivilege))).Count() >= 1 ? temList.Where(t => t.EntitySchemaName == prv.EntitySchemaName && !string.IsNullOrEmpty(t.AssignPrivilege)).First().AssignPrivilege : string.Empty; 227 prv.SharePrivilege = temList.Where(t => t.EntitySchemaName == prv.EntitySchemaName && (!string.IsNullOrEmpty(t.SharePrivilege))).Count() >= 1 ? temList.Where(t => t.EntitySchemaName == prv.EntitySchemaName && !string.IsNullOrEmpty(t.SharePrivilege)).First().SharePrivilege : string.Empty; 228 prv.AppendToPrivilege = temList.Where(t => t.EntitySchemaName == prv.EntitySchemaName && (!string.IsNullOrEmpty(t.AppendToPrivilege))).Count() >= 1 ? temList.Where(t => t.EntitySchemaName == prv.EntitySchemaName && !string.IsNullOrEmpty(t.AppendToPrivilege)).First().AppendToPrivilege : string.Empty; 229 prv.AppendPrivilege = temList.Where(t => t.EntitySchemaName == prv.EntitySchemaName && (!string.IsNullOrEmpty(t.AppendPrivilege))).Count() >= 1 ? temList.Where(t => t.EntitySchemaName == prv.EntitySchemaName && !string.IsNullOrEmpty(t.AppendPrivilege)).First().AppendPrivilege : string.Empty; 230 prv.DeletePrivilege = temList.Where(t => t.EntitySchemaName == prv.EntitySchemaName && (!string.IsNullOrEmpty(t.DeletePrivilege))).Count() >= 1 ? temList.Where(t => t.EntitySchemaName == prv.EntitySchemaName && !string.IsNullOrEmpty(t.DeletePrivilege)).First().DeletePrivilege : string.Empty; 231 returnVal.Add(prv); 232 } 233 return returnVal; 234 } 235 236 //活動實體需要特別處理,替換的時候先替換prvAppendTo,在替換prvAppend,否則獲取不到追加到許可權 237 private static string GetEntitySchemaName(string privelegeName) 238 { 239 string returnVal = string.Empty; 240 returnVal = privelegeName.Replace("prvAssign", ""); 241 returnVal = returnVal.Replace("prvDelete", ""); 242 returnVal = returnVal.Replace("prvRead", ""); 243 returnVal = returnVal.Replace("prvCreate", ""); 244 returnVal = returnVal.Replace("prvWrite", ""); 245 returnVal = returnVal.Replace("prvAppendTo", ""); 246 returnVal = returnVal.Replace("prvAppend", ""); 247 returnVal = returnVal.Replace("prvShare", ""); 248 returnVal = returnVal.Replace("prv", ""); 249 if (returnVal == "Activity") 250 { 251 returnVal = "ActivityPointer"; 252 } 253 return returnVal; 254 } 255 private static string GetEntityDisplayName(string entitySchemaName, Dictionary<string, string> entityMetadata) 256 { 257 string returnVal = string.Empty; 258 if (!string.IsNullOrEmpty(entitySchemaName) && entityMetadata.Where(item => item.Key == entitySchemaName.ToLower()).ToList().Count() >= 1) 259 { 260 returnVal = entityMetadata.Where(item => item.Key == entitySchemaName.ToLower()).First().Value; 261 } 262 return returnVal; 263 } 264 private static int TransferPrivilege(int privilegedepthmask) 265 { 266 int returnVal = -1; 267 switch (privilegedepthmask) 268 { 269 case 8: 270 returnVal = 4; 271 break; 272 case 4: 273 returnVal = 2; 274 break; 275 case 2: 276 returnVal = 2; 277 break; 278 case 1: 279 returnVal = 1; 280 break; 281 } 282 return returnVal; 283 } 284 285 /// <summary> 286 /// 獲取實體架構名稱及其中文顯示名稱 287 /// </summary> 288 /// <param name="orgSvc"></param> 289 /// <returns></returns> 290 private static Dictionary<string, string> GetEntityMetadata(OrganizationServiceProxy orgSvc) 291 { 292 Dictionary<string, string> returnVal = new Dictionary<string, string>(); 293 RetrieveAllEntitiesRequest request = new RetrieveAllEntitiesRequest() 294 { 295 EntityFilters = EntityFilters.Entity, 296 RetrieveAsIfPublished = true 297 }; 298 RetrieveAllEntitiesResponse response = (RetrieveAllEntitiesResponse)orgSvc.Execute(request); 299 foreach (EntityMetadata currentEntity in response.EntityMetadata) 300 { 301 returnVal.Add(currentEntity.LogicalName, 302 currentEntity.DisplayName.LocalizedLabels.Where(a => a.LanguageCode == 2052).Count() >= 1 ? currentEntity.DisplayName.LocalizedLabels.Where(a => a.LanguageCode == 2052).FirstOrDefault().Label : string.Empty); 303 } 304 return returnVal; 305 } 306 307 /// <summary> 308 /// 獲取根業務部門的GUID 309 /// </summary> 310 /// <param name="orgSvc">組織服務</param> 311 /// <returns></returns> 312 private static Guid GetRootBUId(OrganizationServiceProxy orgSvc) 313 { 314 Guid returnVal = Guid.Empty; 315 string fetchXml = @"<fetch version='1.0' mapping='logical' distinct='false' count='1' no-lock='true'> 316 <entity name='businessunit'> 317 <attribute name='businessunitid' /> 318 <filter type='and'> 319 <condition attribute='parentbusinessunitid' operator='null' /> 320 </filter> 321 </entity> 322 </fetch>"; 323 var buEntities = orgSvc.RetrieveMultiple(new FetchExpression(fetchXml)); 324 if (buEntities.Entities.Count >= 1) 325 { 326 returnVal = buEntities.Entities[0].GetAttributeValue<Guid>("businessunitid"); 327 } 328 return returnVal; 329 } 330 } 331 }