یکی از چالش های مدیران شیرپوینت ساخت گزارش از مجوزهای شیرپوینت می باشد ، شما یک مدیر شیرپوینت هستید که دارای لیست ، کتابخانه و سایت های زیر مجموعه ای با مجوز های یکتا و نیز به ارث برده شده از والد می باشد و می خواهید به جواب سوالات زیر برسید:
- یک کاربر خاص به چه فایل هایی ، لیست هایی و سایت هایی دسترسی دارد؟ تحت کدام گروه کاری ؟ چه نوع دسترسی؟
- چگونه گزارشی بسازم برای کتابخانه با بیش از5000 هزار فایل با مجوز دسترسی یکتا که برای هر فایل مشخص کند افرادی با چه سطح دسترسی می توانند ببینند؟
- جگونه گزارشم از سطح فارم تا فایل در شیرپوینت همیشه آماده باشد؟
- و…
سوالات بیشتر دیگری در این موارد می توان بیان کرد اما جذاب تر از آن بیان راه حل این سوالات می باشد.
در این مقاله ساخت گزارش از مجوزهای شیرپوینت به کمک Power Shell با روشی کاملا کاربردی که خودم در 3 فارم شیرپوینت از آن بهره می برم با ترکیب سه ابزار مایکروسافت به این سوالات پاسخ بدهم که عبارتند از:
- Power Shell
- Windows Task Schedule
- Power BI Report Server
مرحله ا:ساخت گزارشی با کمک Power Shell
ابتدا به کمک کد پاورشل یک گزارش تولید می کنیم که با تغییر سه متغییر زیر یک فایل CSV می سازد از وب اپلیکشن شما
- نام وب اپلیکیشن
- محل ذخیره سازی فایل CSV
این متغییر ها را باید به ترتیب روبه روی تابع GetUserAccessReport در آخرین خط اسکریپت در کد زیر جایگزنی کنید:
Add-PSSnapin Microsoft.SharePoint.PowerShell -ErrorAction SilentlyContinue Function GetUserAccessReport($WebAppURL, $FileUrl) { Write-Host "Generating permission report..." #Get All Site Collections of the WebApp $SiteCollections = Get-SPSite -WebApplication $WebAppURL -Limit All #Write CSV- TAB Separated File) Header "URL`tSite/List/Folder/Item`tTitle/Name`tPermissionType`tPermissions `tLoginName" | out-file $FileUrl #Check Web Application Policies $WebApp= Get-SPWebApplication $WebAppURL foreach ($Policy in $WebApp.Policies) { $PolicyRoles=@() foreach($Role in $Policy.PolicyRoleBindings) { $PolicyRoles+= $Role.Name +";" } "$($AdminWebApp.URL)`tWeb Application`t$($AdminSite.Title)`tWeb Application Policy`t$($PolicyRoles)`t$($Policy.UserName)" | Out-File $FileUrl -Append } #Loop through all site collections foreach($Site in $SiteCollections) { #Check Whether the Search User is a Site Collection Administrator foreach($SiteCollAdmin in $Site.RootWeb.SiteAdministrators) { "$($Site.RootWeb.Url)`tSite`t$($Site.RootWeb.Title)`tSite Collection Administrator`tSite Collection Administrator`t$($SiteCollAdmin.LoginName)" | Out-File $FileUrl -Append } #Loop throuh all Sub Sites foreach($Web in $Site.AllWebs) { if($Web.HasUniqueRoleAssignments -eq $True) { #Get all the users granted permissions to the list foreach($WebRoleAssignment in $Web.RoleAssignments ) { #Is it a User Account? if($WebRoleAssignment.Member.userlogin) { #Get the Permissions assigned to user $WebUserPermissions=@() foreach ($RoleDefinition in $WebRoleAssignment.RoleDefinitionBindings) { $WebUserPermissions += $RoleDefinition.Name +";" } #Send the Data to Log file "$($Web.Url)`tSite`t$($Web.Title)`tDirect Permission`t$($WebUserPermissions) `t$($WebRoleAssignment.Member.LoginName)" | Out-File $FileUrl -Append } #Its a SharePoint Group, So search inside the group and check if the user is member of that group else { foreach($user in $WebRoleAssignment.member.users) { #Get the Group's Permissions on site $WebGroupPermissions=@() foreach ($RoleDefinition in $WebRoleAssignment.RoleDefinitionBindings) { $WebGroupPermissions += $RoleDefinition.Name +";" } #Send the Data to Log file "$($Web.Url)`tSite`t$($Web.Title)`tMember of $($WebRoleAssignment.Member.Name) Group`t$($WebGroupPermissions)`t$($user.LoginName)" | Out-File $FileUrl -Append } } } } #******** Check Lists, Folders, and Items with Unique Permissions ********/ foreach($List in $Web.lists) { if($List.HasUniqueRoleAssignments -eq $True -and ($List.Hidden -eq $false)) { #Get all the users granted permissions to the list foreach($ListRoleAssignment in $List.RoleAssignments ) { #Is it a User Account? if($ListRoleAssignment.Member.userlogin) { #Get the Permissions assigned to user $ListUserPermissions=@() foreach ($RoleDefinition in $ListRoleAssignment.RoleDefinitionBindings) { $ListUserPermissions += $RoleDefinition.Name +";" } #Send the Data to Log file "$($List.ParentWeb.Url)/$($List.RootFolder.Url)`tList`t$($List.Title)`tDirect Permission`t$($ListUserPermissions) `t$($ListRoleAssignment.Member)" | Out-File $FileUrl -Append } #Its a SharePoint Group, So search inside the group and check if the user is member of that group else { foreach($user in $ListRoleAssignment.member.users) { #Get the Group's Permissions on site $ListGroupPermissions=@() foreach ($RoleDefinition in $ListRoleAssignment.RoleDefinitionBindings) { $ListGroupPermissions += $RoleDefinition.Name +";" } #Send the Data to Log file "$($List.ParentWeb.Url)/$($List.RootFolder.Url)`tList`t$($List.Title)`tMember of $($ListRoleAssignment.Member.Name) Group`t$($ListGroupPermissions)`t$($user.LoginName)" | Out-File $FileUrl -Append } } } } #Get Folder level permissions foreach($Folder in $List.folders) { if($Folder.HasUniqueRoleAssignments -eq $True) { #Get all the users granted permissions to the folder foreach($FolderRoleAssignment in $Folder.RoleAssignments ) { #Is it a User Account? if($FolderRoleAssignment.Member.userlogin) { #Get the Permissions assigned to user $FolderUserPermissions=@() foreach ($RoleDefinition in $FolderRoleAssignment.RoleDefinitionBindings) { $FolderUserPermissions += $RoleDefinition.Name +";" } #Send the Data to Log file "$($Folder.Web.Url)/$($Folder.Url)`tFolder`t$($Folder.Title)`tDirect Permission`t$($FolderUserPermissions) `t$($FolderRoleAssignment.Member)" | Out-File $FileUrl -Append } #Its a SharePoint Group, So search inside the group and check if the user is member of that group else { foreach($user in $FolderRoleAssignment.member.users) { #Get the Group's Permissions on site $FolderGroupPermissions=@() foreach ($RoleDefinition in $FolderRoleAssignment.RoleDefinitionBindings) { $FolderGroupPermissions += $RoleDefinition.Name +";" } #Send the Data to Log file "$($Folder.Web.Url)/$($Folder.Url)`tFolder`t$($Folder.Title)`tMember of $($FolderRoleAssignment.Member.Name) Group`t$($FolderGroupPermissions)`t$($user.LoginName)" | Out-File $FileUrl -Append } } } } } #Get Item level permissions foreach($Item in $List.items) { if($Item.HasUniqueRoleAssignments -eq $True) { #Get all the users granted permissions to the item foreach($ItemRoleAssignment in $Item.RoleAssignments ) { #Is it a User Account? if($ItemRoleAssignment.Member.userlogin) { #Get the Permissions assigned to user $ItemUserPermissions=@() foreach ($RoleDefinition in $ItemRoleAssignment.RoleDefinitionBindings) { $ItemUserPermissions += $RoleDefinition.Name +";" } #Prepare item's absolute Url and Name $ItemDispForm = $Item.ParentList.Forms | where { $_.Type -eq "PAGE_DISPLAYFORM" } | Select-Object -first 1 if ($ItemDispForm.Url) { $ItemUrl = "$($Item.Web.Url)/$($ItemDispForm.Url)?ID=$($Item.ID)" } else { $ItemUrl = "$($Item.Url)" } if ($Item.Name) { $ItemTitle = $Item.Name } else { $ItemTitle = $Item.Title } #Send the Data to Log file "$($ItemUrl)`tItem`t$($ItemTitle)`tDirect Permission`t$($ItemUserPermissions) `t$($ItemRoleAssignment.Member)" | Out-File $FileUrl -Append } #Its a SharePoint Group, So search inside the group and check if the user is member of that group else { foreach($user in $ItemRoleAssignment.member.users) { #Get the Group's Permissions on site $ItemGroupPermissions=@() foreach ($RoleDefinition in $ItemRoleAssignment.RoleDefinitionBindings) { $ItemGroupPermissions += $RoleDefinition.Name +";" } #Prepare item's absolute Url and Name $ItemDispForm = $Item.ParentList.Forms | where { $_.Type -eq "PAGE_DISPLAYFORM" } | Select-Object -first 1 if ($ItemDispForm.Url) { $ItemUrl = "$($Item.Web.Url)/$($ItemDispForm.Url)?ID=$($Item.ID)" } else { $ItemUrl = "$($Item.Url)" } if ($Item.Name) { $ItemTitle = $Item.Name } else { $ItemTitle = $Item.Title } #Send the Data to Log file "$($ItemUrl)`tItem`t$($ItemTitle)`tMember of $($ItemRoleAssignment.Member.Name) Group`t$($ItemGroupPermissions)`t$($user.LoginName)" | Out-File $FileUrl -Append } } } } } } } } } #Call the function to Check User Access GetUserAccessReport "http://portal.example.ir" "E:\SharePoint_Permission_Report.csv"
پس از اجرای این اسکریپت در PowerShell ISE ویندوز سرور نتیجه را در محل ذخیره فایل Csv مشاهده می کنید
فایل CSV را می توانید به کمک ماکروسافت اکسل باز کنیدکه دارای ستونهایی می باشدکه می توانید آن را به آسانی آنالیز کنید به کمک فیلتر کردن ستون های زیر که نیازی به شرح ندارند برای مثال من نام کاربری خودم را فیلتر می کنم تا دسترسی هایم مشخص شود.
خب تا اینجای کار نیاز بسیاری از شما مدیران سایت مرتفع می شود اما بگذارید یک گام فراتر برویم و این پروسه را ابتدا بروز کنیم و سپس مصور سازی کنیم
مرحله 2: بروزرسانی دوره ای فایل CSV
من در مقاله ساخت یک فعالیت زمانبندی شده برای Power Shell روش ساخت یک فعالیت زمانبندی شده به کمک Windows Task Schedule را شرح دادم تنها کاری که شما باید انجام بدید اینه که ابتدا یک فایل متنی بسازید و کد فوق را درآن کپی کنید سپس با پسوند ps1ذخیره کنید و سپس با توجه به مقاله ساخت یک فعالیت زمانبندی شده برای Power Shell آن را تبدیل به یک فعالیت زمانبندی شده کنید تا مثلا هر شب ساعت 1 بامداد اجرا شود و فایل جدید جایگزین فایل قبلی شود. بدین ترتیب فایل بروز گزارش را همیشه در اختیار دارید.
در بعضی از موارد نیاز می باشد که در هر بار بروز شدن شما یک فایل جدید بسازید ، این کار را می توانید با اضافه کردن کدی که نام فایل را تغییر دهد انجام دهید.
مرحله 3: ساخت گزارش از فایل CSV و بروز رسانی آن
این مرحله اختیاری می باشد و شما می توانید به تناسب نیاز خود آن را تغییر بدهید ، جهت مصور سازی فایل CSV به سراغ نرم افزار Power BI می رویم از منوی Get Data گزینه CSV را انتخاب می کنیم و آدرس فایل مربوطه را به آن می دهیم
دکمه Edit را بزنید و اولین ردیف را به عنوان هدر ستون انتخاب کنید و دکمه Apply را بزیند.
سپس یک داشبورد از فایل مربوطه متناسب به نیازتان می سازیم سپس آن را Publish کنید
با توجه به نوع سرویس خود تنظیمات بروز رسانه را حداقل 15 بعد از بروز رسانی فعالیت بروزرسانی فایل CSV اعمال کنید چون اجرای اسکریپت مورد نظر در پاورشل در فارم های بزرگ زمان بر می باشد.
شما می توانید داشبورد مورد نظرخود را برای موبایل نیز تنظیم کنید تا در هر زمان و مکان بتوانید دسترسی های وب اپلیکیشن خود را چک کنید.
مراحل به پایان رسید.
سلام وقت بخیر
ممنون از مطلب آموزشی بسیار پرکاربردتون. من فایل CSV از تمامی دسترسی های موجود در شیرپوینت رو ایجاد کردم. آیا امکانی وجود داره که از طریق فایل اکسل دسترسی هایی رو به شیرپوینت import کنم؟