power bi service user all log

Merhabalar, iyi günler.

Bugün Microsoft’un birbirinden bağımsız veri kaynaklarınızı tutarlı, görsel olarak sürükleyici ve etkileşimli öngörülere dönüştürmenizi sağlamak için birlikte çalışan yazılım hizmetlerinden, uygulamalardan ve bağlayıcılardan oluşan bir koleksiyonu olan Power BI’ın PowerShell üzerinde kullanıcı bilgi ve işlem takibi adına neler yapılabileceğine yönelik aktarımlarda bulunmaya çalışacağım.

Şimdiden iyi okumalar.

***

Günümüz süreç ve iş faaliyetleri karmaşıklığından dolayı kurumsal organizasyonlarda; uygulamalar, raporlar, çalışma alanları, veri kaynakları ve kullanıcalar sayıca olağan değerlerin üzerinde olabilir.

Bu durumlara yönelik farklı yöntemler ile organizasyonel kullanım metrikleri takip altına alınmalı ya da süreklilik sağlayan bir iş kaynağı üzerinde bilgi bankası olarak veri niteliğinde biriktirilmelidir.

Bu işlem mekanizmasına yönelik ele almaya çalışacağımız başlıklara değinmeden önce; dilerseniz ön bilgi adına, konuya giriş bilgileri içeren PowerShell üzerinde Power BI Kullanımı yazısına göz atabilirsiniz.

Konumuza geri dönüp, bugünkü yazı içeriğinde değinmeye çalışacağımız PowerShell ile Power BI üzerinde;

  • Kullanıcı Listesi
  • Kullanıcı Dökümleri/Özetleri,
  • Kullanıcı Eylemleri/İşlemleri

bilgilerine/konularına geçişte bulunalım.

İlk olarak;

Kurumsal Power BI sistemlerinde anlık olarak elde edebileceğiniz ya da ulaşabileceğiniz bir kullanıcı listesi bulunmamaktadır.
*Microsoft 365 Admin Center üzerinden lisanslar filtrelenerek elde edilebilir.

Bunu basit birkaç kod ile PowerShell üzerinden anlık olarak elde edebiliriz.
Dilerseniz hızlıca çalışmamıza başlayalım.

Öncelikle Power BI hizmetine bağlanalım;

Connect-PowerBIServiceAccount

Yanı sıra;

Login-PowerBIServiceAccount

ya da

Login-PowerBI

kod bloklarını da kullanılarak Power BI hizmetine bağlantı erişimi adına talepte bulunabilirsiniz.

Kod bloğumuzu çalıştırdığımızda alt kısımda ki gibi bir hata ile karşılaşabiliriz;

power bi powershell login error failed linkid=135170

İlgili hata;

File C:\Users\user\Desktop\POWER BI KULLANICI BILGI VE ISLEM GECMISI.ps1 cannot be loaded because running scripts is disabled on this system. For more information, see about_Execution_Pol
icies at https:/go.microsoft.com/fwlink/?LinkID=135170.
    + CategoryInfo          : SecurityError: (:) [], ParentContainsErrorRecordException
    + FullyQualifiedErrorId : UnauthorizedAccess

şeklindedir.

Hatayı aşabilmek için öncelikle ilgili yerel cihazınızdaki güvenlik ve yürütme politikalarına göz atmanız gerekebilir.
Ardından;

bağlantısı üzerinden cihazınız ve kurumsal protokollerinize uygun politikayı seçip uygulayabilirsiniz.

Düzenleme gerçekleştirildiğinde ise;

power bi powershell login error failed linkid=135170 solved
power bi powershell login success

sisteme erişebildiğimiz görüntülenmektedir.

Şimdi sisteme giriş yapıp, ön bilgilere erişmeye başlayalım.
Tabi öncelikle kullanıcı listesi erişim ve çıktı mantığımızı kurgulayalım.
Kurgumuz; organizasyonda yer alan tüm çalışma alanlarını listeleyip, sonrasında bu alanların tanımlıyıcılarını (Identifier) derleyip bir liste haline dönüştürmek olsun.
*En nihayetinde Power BI hizmetlerinde yer alan tüm kullanıcıların bireysel çalışma alanları mevcut.

Tamam o zaman.
Hızlıca önceki yazımızdan edindiğimiz kodları kullanarak organizasyonda yer alan tüm çalışma alanlarına erişelim;

Get-PowerBIWorkspace -Scope Organization -Include All -All
power bi powershell all workspaces detail

Erişim sonrasında UserPrincipalName (Kullanıcı Asıl Adı) ya da Identifier (Tanımlayıcı) alanlarını listeleme için kullanabileceğimizi görüntülemekteyiz.

Tercihen düşündüğümüzde ise;
UPN (User Principal Name) Azure üzerinde opsiyonel tercih edilebilir bir alan olarak sistemde yer almaktadır;

azure active directory user principal name alt login id

Sonrasında oluşturulacak log geçmişi takibi gibi çalışmalarda tablolar arası kullanıcı ilişkisi kurarken bu durum ilişki problemi oluşturabilir.Bu nedenden dolayı Identifier alanını tercih edebiliriz.

Peki o zaman tercihimizi şimdi kod satırı üzerinde bir sonraki adım olarak yansıtalım, öncelikle çalışma alanını bir kullanıcı listesi olarak parametreye tanımlayarak bu parametre üzerine atayalım;

$UserList = Get-PowerBIWorkspace -Scope Organization -Include All -All

Oluşan parametre üzerinden ise Identifier bilgisine ulaşalım;

$UserList.Users.Identifier

*UserList bir kolleksiyon olarak düşünülebilir, içerisinde birden çok nesne varmışçasına.
Bu nesnelerden Users’a (Kullanıcılar) erişip alt özelliği olan Identifier’e ulaşmaya çalışıyorum gibi de mevcut işlem kurgulanabilir.

İlgili kod çalıştırıldığında ise;

power bi powershell user identifier information

mevcut organizasyon üzerindeki kullanıcıları bir liste olarak elde edebildiğim görüntülenmektedir.
Fakat burada tekrarlı kullanıcılar olduğu görüntülenmektedir.
Bu; farklı alanlarda yer aldıkları, farklı erişim izinleri tanımlanmış olduğu vb. manalara karşılık gelmektedir.

İlgili listeyi tekilleştirmek istediğimizde ise;

$UniqueUserList = $UserList.Users.Identifier | Group-Object

listemdeki öğeleri gruplayıp yeni bir parametreye atadığımda, bu parametre üzerinden ilgili bilgiye özet halde ulaşabileceğim.
operatörü çeşitli işlem tanımlaması gerçekleştirileceğini ifade etmektedir.
*Group Object ilgili değere göre çıktı sonucunu gruplamaktadır.

Oluşturmuş olduğum yeni parametre üzerinden Identifier‘ın Name (Ad) kısmına ulaştığımda ise;

$UniqueUserList.Name
power bi powershell user unique identifier information

listenin tekil hale gelmiş olduğunu görüntülemekteyiz.

Ufak bir ek ile kaç adet kullanıcı olduğunu kontrol ettiğimizde ise; 

$UniqueUserList.Name.Count
power bi powershell user unique identifier information count

sonucuna ulaşmaktayız.

Buraya kadar herşey güzel.
Şimdi edinmiş olduğumuz bu bilgileri nasıl kullanacağız, ya da ne için?
Yani; bir raporlama sistemine mi aktarılacak, belirli bir alanda dosya olarak mı yedeklenecek ya da çeşitli nedenler için bir kereye mahsus olarak mı kullanılacak.

Hepsini kapsayacak bir adım ile devam edelim.
Raporlama sistemi kurulması ve verilerin denetlenmesi adına edindiğimiz bilgileri MsSQL üzerine aktarıp kayıt altına alalım.
*Dilediğiniz depolama sistemi ya da yöntemi üzerinde çalışmada bulunabilirsiniz.

Bu noktadan sonra gerçekleştireceğimiz; veri kaynağı erişimi, veri sorgulaması ve veri aktarımı işlemlerini ise Microsoft’un ADO.Net* teknolojisi ile gerçekleştireceğiz.

*Ado.Net; Microsoft’un veriye erişme teknolojisine tanımlamış olduğu addır.
ActiveX teknolojisi ile geliştirilmiş bir çözümdür.

Gerçekleştireceğimiz bu işlemler için ise öncelikli olarak;

  • Server Name (Sunucu Adı)
  • Database Name (Veritabanı Adı)
  • Table Name (Tablo Adı)
  • Connection Type (Bağlantı Tipi)
bilgilerine ihtiyaç duymaktayız.
Belirtilen bilgilere ulaşıp/edinip bunu Shell üzerinde parametrik kullanılabilir bir formata dönüştürelim.
Yani;
$serverName   = " SUNUCU ADINIZ "
$databaseName = " ILGILI VERITABANI "
$tableName    = " ILGILI TABLO "
$Connection.ConnectionString = "server='$serverName';database='$databaseName';trusted_connection=true;"

şeklinde kullanıma hazırlayalım.

Peki; bağlantının yanı sıra, bağlanma (Connection) ve işlem ermi (Command) için gerçekleştirilecek işlemler adına iki adet obje oluşturmamız gerekmektedir.
Bunun için System.Data.SQLClient kütüphanesinden yardım alabiliriz.

İlgili kütphane üzerinden objelerimizi;

$Connection = New-Object System.Data.SQLClient.SQLConnection
$Command    = New-Object System.Data.SQLClient.SQLCommand

şeklinde parametrik kullanılabilir bir yapıda oluşturabiliriz.
Buraya kadar bağlantı bilgisi ve bağlantı-işlem gerçekleştiren objelerimiz hazır.

Şimdi ise bağlantı bilgileri ile bağlantı açıp-kapatmamız gerekmekte.
Bunu da tekrar ADO.Net ile sağlayabiliriz;

$Connection.Open()
$Connection.Close();

Bağlantıyı Açıp-Kapatma nedeni ise (sadece biri); SqlConnection’ın bir bağlantı havuzu yapısı vardır.
Open() ve Close()’u çağırdığımızda aslında sunucuyla olan fiziksel bağlantıyı açıp kapatmıyoruz.
Sadece mevcut bağlantı havuzuna bağlantıyı ekliyor/kaldırıyoruz.
Bu nedenle komutunuzu yürüttükten sonra bağlantıyı mümkün olduğunca geç açmak (Sadece sunucu işlemleri kaldığında) ve bağlantıyı mümkün olduğunca erken kapatmak (Sunucu işlemleri bittiğinde) güvenlik, kaynak kullanımı ve süreç bütünlüğü adına önerilmektedir.

Geldiğimiz nokta dahilinde; bağlantı bilgisi, bağlantı-işlem gerçekleştiren objeler ve bağlantı yürütücülerimiz hazır.
Şimdi ilgili edindiğimiz bilgileri kaynağımıza aktarma kısmına geldik.
Tekrar süreci düşünecek olursak; organizasyon üzerindeki farklı çalışma alanlarını tek-tek gezip bunları tekil olarak gruplayıp bir liste oluşturacaktık.
Aslında bakıldığında bir işlem döngüsü mevcut, aynı mantıkta veri iletilirken bir döngü kurmamız gerekmekte.

Bunu da foreach() döngüsü çözüm metodu ile gerçekleştirebiliriz.
Burada ilgili Identifier bilgilerini tek-tek veri tabanı üzerine kayıt etmeye çalışacağız.

İlgili ana bloğumuz;

foreach($item in $UniqueUserList)
{
 #ILGILI KAYIT ISLEMLERI.
}

şeklindedir.

Bu blok içerisinde ise; ilgili veriyi çeken, belirtilen tabloya gönderen ve gönderilen tabloda kayıt altına alan bir işlem parçacığı oluşturmamız gerekmektedir.

Bunun için de tekrardan ADO.Net üzerine dönüp, kısmi SQL bilgileri ile kod bloğu oluşturulduğunda; 

  $UserIdentifier=$item.Name

  $insertquery         = "INSERT INTO $tableName([UserIdentifier])VALUES('$UserIdentifier')"
  $Command.CommandText = $insertquery
  $Command.ExecuteNonQuery()

kullanılabilir bir formatta ele alabiliriz.

Parçalar halinde oluşturduğumuz kodları ana blok haline dönüştürdüğümüzde ise;

$serverName                  = " SUNUCU ADINIZ "
$databaseName = " ILGILI VERITABANI "
$tableName = " ILGILI TABLO "
$Connection = New-Object System.Data.SQLClient.SQLConnection $Connection.ConnectionString = "server='$serverName';database='$databaseName';trusted_connection=true;" $Connection.Open() $Command = New-Object System.Data.SQLClient.SQLCommand $Command.Connection = $Connection foreach($item in $UniqueUserList) { $UserIdentifier = $item.Name $insertquery = "INSERT INTO $tableName([UserIdentifier])VALUES('$UserIdentifier')" $Command.CommandText = $insertquery $Command.ExecuteNonQuery() } $Connection.Close();

görüntüsünü elde etmekteyiz.

Bu kısma kadar PowerShell üzerindeki yapımızı planlayıp, kurguladık; bundan sonra ufak bir işlem ile MsSQL üzerinde ilgili veritabanı ve tablomuzu oluşturalım.

Sunucu üzerinde PowerBIServiceLog adında veritabanı ve Users adında bir tablo oluşturalım;
*Tablo veri tipi uygun formatlarda düzenlenebilir.

power bi powershell user information insert mssql

Herşey hazır olduğuna göre ana PowerShell kod ekranımıza dönüp kodumuzu çalıştıralım;

power bi powershell user information insert mssql script

herhangi bir hata oluşmadı fakat ard-arda 7 tane 1 değeri yazıldı ekrana;

power bi powershell user information mssql script

Bu; foreach() döngüsünde yer alan herbir kullanıcı Identifier bilgisinin yazılması anında gerçekleşti.
Peki MsSQL üzerindeki tablomuza dönecek olursak;

power bi powershell user information mssql table

mevcut kullanıcı listesi verileri kayıt altına alınmış oldu.

PowerShell üzerinden Power BI İşlem Geçmişine Ulaşılması

Temel kullanıcı tablomuzu oluşturmuş olduk, şimdi ise bu kullanıcıların hareketlerine göz atma vakti.
Burda PowerBIAudit hizmeti üzerinden kullanıcı işlem geçmişlerine erişmeye çalışacağız.

Bu bilgilere erişim normal şartlar altında bir panel üzerinde zaman aralığı ve eylem tipi dahilindedir;

power bi powershell user audit information

Biz bunu tekrar parametrik bir yapıda (Üst örneklerdeki gibi) kurgulayıp MsSQL’e aktarmaya çalışacağız.
PowerBIAudit sistemine erişimimizi üst kısımdaki Power BI Service erişiminden farklı olarak sabit değer girerek gerçekleştirmeye çalışalım.
*Hard Coding olarak planlayalım, sonrasında zamanlanmış görevlerde kullanabiliriz.

Yani kullanıcı adı ve parolayı parametreye atalım ve bu parametreleri giriş yaparken sabitler olarak kullanalım;

$PBIAdminUPN = " KULLANICI ADI/MAIL "
$PBIAdminPW  = " KULLANICI PAROLASI "

Bu bilgileri de Power BI servisine parametre olarak iletip, erişim kontrolünde bulunalım;
*System.Managment.Automation kütüphanesine erişip PSCredential methodundan faydalanalım.

$Security    = ConvertTo-SecureString $PBIAdminPW -AsPlainText -Force
$Credential  = New-Object System.Management.Automation.PSCredential($PBIAdminUPN,$Security)

Connect-PowerBIServiceAccount -Credential $Credential
power bi powershell user audit service login

Görüntülendiği gibi servise erişebiliyoruz.
İkinci adım olarak dinamik bir tarih aralığı vermemiz gerekiyor.
Normal kullanım dahilinde PowerBI loglarına başlangıç ve bitiş tarihini sabit verip, kullanabiliriz;

Get-PowerBIActivityEvent -StartDateTime '2022-11-12T00:00:00.000' -EndDateTime '2022-11-12T23:59:59.999' | ConvertFrom-Json

*Yanıt bilgilerini (Response) Json formatında elde ediyoruz.

Fakat bizim bu tarih formatı kullanım mantığını biraz değiştirip, dinamikleştirmemiz gerekmektedir;

-StartDateTime '2022-11-12T00:00:00.000' -EndDateTime '2022-11-12T23:59:59.999'

Çözüm olarak ise tüm tarih/zaman öğelerini (Yıl,Ay,Gün,Saat) parçalara ayırıp yeniden parametrik hale getirmek uygun gibi görünmektedir.

O zaman önce mevcut işlem tarihini “Kaç gün geriye gidecek” mantığında dinamik olarak belirleyelim;
*Şuan 1 gün geriye.
*Get-Date fonskiyonu anlık mevcut gün bilgisini değer olarak geri döndürmektedir. 

$StartDate = Get-Date
$StartDate = $StartDate.AddDays(-1)

Bu gün değerini kullanarak, tüm tarih/zaman öğeleri (Yıl,Ay,Gün,Saat) için formatımızı yeniden oluşturalım;

$StartDateYearStr  = $StartDate.ToString('yyyy')
$StartDateMonthStr = $StartDate.ToString('MM')
$StartDateDayStr   = $StartDate.ToString('dd')

$StartLogDate = $StartDateYearStr + '-' + $StartDateMonthStr + '-' + $StartDateDayStr + 'T00:00:00.000'
$EndLogDate   = $StartDateYearStr + '-' + $StartDateMonthStr + '-' + $StartDateDayStr + 'T23:59:59.999'

Şuan için parametrik zaman planı kullanılabilir formatta oluşturulmuş gözükmektedir.
Bunu log günlüğüne dahil edelim;

$ActivityLogs = Get-PowerBIActivityEvent -StartDateTime $StartLogDate -EndDateTime $EndLogDate | ConvertFrom-Json

Buraya kadar herşey güzel gibi.
Şimdi ilgili objemize erişip, parametreleri edinmemiz lazım.
Power BI log sistemi üzerinde alt kısımda yer alan parametrik alanlar kayıt altında tutulmaktadır;
*Bireysel SQL formatı görünümü.

  ActivityLogINTernalID VARCHAR(50) NULL
 ,RecordType INT NULL
 ,CreationTime DATETIME NULL
 ,Operation VARCHAR(100) NULL
 ,OrganizationID VARCHAR(50) NULL
 ,UserType INT NULL
 ,UserKey VARCHAR(200) NULL
 ,Workload VARCHAR(100) NULL
 ,UserID VARCHAR(500) NULL
 ,ClientIP VARCHAR(50) NULL
 ,UserAgent VARCHAR(1000) NULL
 ,Activity VARCHAR(100) NULL
 ,ItemName NVARCHAR(500) NULL
 ,ObjectID VARCHAR(500) NULL
 ,RequestID VARCHAR(50) NULL
 ,ActivityID VARCHAR(50) NULL
 ,IsSuccess BIT NULL
 ,WorkspaceName NVARCHAR(500) NULL
 ,WorkspaceID VARCHAR(50) NULL
 ,ImportID VARCHAR(50) NULL
 ,ImportSource VARCHAR(50) NULL
 ,ImportType VARCHAR(50) NULL
 ,ImportDisplayName NVARCHAR(500) NULL
 ,DatasetName NVARCHAR(500) NULL
 ,DatasetID VARCHAR(50) NULL
 ,DataConnectivityMode VARCHAR(200) NULL
 ,GatewayID VARCHAR(50) NULL
 ,GatewayName NVARCHAR(500) NULL
 ,GatewayType VARCHAR(100) NULL
 ,ReportName NVARCHAR(500) NULL
 ,ReportID VARCHAR(50) NULL
 ,ReportType VARCHAR(100) NULL
 ,FolderObjectID VARCHAR(50) NULL
 ,FolderDisplayName NVARCHAR(500) NULL
 ,ArtifactName NVARCHAR(500) NULL
 ,ArtifactID VARCHAR(50) NULL
 ,CapacityName VARCHAR(200) NULL
 ,CapacityUsers NVARCHAR(4000) NULL
 ,CapacityState VARCHAR(100) NULL
 ,DistributionMethod VARCHAR(100) NULL
 ,ConsumptionMethod VARCHAR(100) NULL
 ,RefreshType VARCHAR(100) NULL
 ,ExportEventStartDATETIMEParameter VARCHAR(50) NULL
 ,ExportEventEndDATETIMEParameter VARCHAR(50) NULL
 ,ExportedArtifactExportType VARCHAR(50) NULL
 ,ExportedArtifactType VARCHAR(50) NULL
 ,AuditedArtifactName NVARCHAR(500) NULL
 ,AuditedArtifactObjectID VARCHAR(50) NULL
 ,AuditedArtifactItemType VARCHAR(50) NULL
 ,OtherDatasetIDs VARCHAR(4000) NULL
 ,OtherDatasetNames NVARCHAR(4000) NULL
 ,OtherDatasourceTypes VARCHAR(4000) NULL
 ,OtherDatasourceConnectionDetails VARCHAR(4000) NULL
 ,SharingRecipientEmails NVARCHAR(4000) NULL
 ,SharingResharePermissions VARCHAR(4000) NULL
 ,SubscribeeRecipientEmails NVARCHAR(4000) NULL
 ,SubscribeeRecipientNames NVARCHAR(4000) NULL
 ,SubscribeeObjectIDs VARCHAR(4000) NULL

Biz bunların bir kısmını alacağız, opsiyonel olarak genişletebilirsiniz.
Bu bilgileri veritabanı üzerine aktarırken ilgili objenin ilk kaydından (İlk indis=0) başlayarak kullanıcılar üzerinde uyguladığımız gibi foreach() döngüsü ile kayıt işlemi gerçekleştiriyor olacağız.

Bu uyarlamayı koda aktaracak olursak;

$MaxValue = $ActivityLogs.Count

en büyük log kaydı satır değerini bulup;

 foreach($item in $ActivityLogs[$i])

döngü içerisine değer aralığı üzerinde işlemde bulunabildiğimiz for() döngüsüne atayacağız.
Yani genel kod bloğumuz;

for($i = 0; $i -lt $MaxValue; $i++)
{
        foreach($item in $ActivityLogs[$i])
        {
        }
}

şeklinde olacaktır.
Kayıt altına alınacak parametreleri, sorgu içerisinde kullanıcılar işlem formatımızda kullandığımız gibi revize edecek olursak; 

for($i = 0; $i -lt $MaxValue; $i++)
{
        foreach($item in $ActivityLogs[$i]){
                $Id=$item.Id
                $UserType=$item.UserType
                $UserKey=$item.UserKey
                $Workload=$item.Workload
                $UserId=$item.UserId
                $Activity=$item.Activity
                $ItemName=$item.ItemName
                $CreationTime=$item.CreationTime
                $CreationTimeUTC=$item.CreationTimeUTC
                $RecordType=$item.RecordType
                $Operation=$item.Operation
                $OrganizationId=$item.OrganizationId
                $ClientIP=$item.ClientIP
                $UserAgent=$item.UserAgent
                $WorkSpaceName=$item.WorkSpaceName
                $DashboardName=$item.DashboardName
                $DatasetName=$item.DatasetName
                $ReportName=$item.ReportName
                $WorkspaceId=$item.WorkspaceId
                $ObjectId=$item.ObjectId
                $DashboardId=$item.DashboardId
                $DatasetId=$item.DatasetId
                $OrgAppPermission=$item.OrgAppPermission
                $CapacityId=$item.CapacityId
                $CapacityName=$item.CapacityName
                $AppName=$item.AppName
                $IsSuccess=$item.IsSuccess
                $ReportType=$item.ReportType
                $ReportId=$item.ReportId
                $RequestId=$item.RequestId
                $ActivityId=$item.ActivityId
                $AppReportId=$item.AppReportId
                $DistributionMethod=$item.DistributionMethod
                $ConsumptionMethod=$item.ConsumptionMethod

      $insertquery="
      INSERT INTO $tableName
          (
           [Id],
           [UserType],
           [UserKey],
           [Workload],
           [UserId],
           [Activity],
           [ItemName],
           [CreationTime],
           [CreationTimeUTC],
           [RecordType],
           [Operation],
           [OrganizationId],
           [ClientIP],
           [UserAgent],
           [WorkSpaceName],
           [DashboardName],
           [DatasetName],
           [ReportName],
           [WorkspaceId],
           [ObjectId],
           [DashboardId],
           [DatasetId],
           [OrgAppPermission],
           [CapacityId],
           [CapacityName],
           [AppName],
           [IsSuccess],
           [ReportType],
           [ReportId],
           [RequestId],
           [ActivityId],
           [AppReportId],
           [DistributionMethod],
           [ConsumptionMethod]
          )
        VALUES
          (
            '$Id',
            '$UserType',
            '$UserKey',
            '$Workload',
            '$UserId',
            '$Activity',
            '$ItemName',
            '$CreationTime',
            '$CreationTimeUTC',
            '$RecordType',
            '$Operation',
            '$OrganizationId',
            '$ClientIP',
            '$UserAgent',
            '$WorkSpaceName',
            '$DashboardName',
            '$DatasetName',
            '$ReportName',
            '$WorkspaceId',
            '$ObjectId',
            '$DashboardId',
            '$DatasetId',
            '$OrgAppPermission',
            '$CapacityId',
            '$CapacityName',
            '$AppName',
            '$IsSuccess',
            '$ReportType',
            '$ReportId',
            '$RequestId',
            '$ActivityId',
            '$AppReportId',
            '$DistributionMethod',
            '$ConsumptionMethod'
           )"
      $Command.CommandText = $insertquery
      $Command.ExecuteNonQuery()
    }
}

görünümüne ulaşıyor olacağız.
Aynı alanları MsSQL üzerinde tablo formatında oluşturduğumuzda ise;

power bi powershell user audit information mssql table format

görünümüne ulaşacağız.

Parçalar halinde oluşturduğumuz kodları ana blok haline dönüştürdüğümüzde ise;

$PBIAdminUPN="[email protected]"
$PBIAdminPW ="                     "

$Security     = ConvertTo-SecureString $PBIAdminPW -AsPlainText -Force
$Credential   = New-Object System.Management.Automation.PSCredential($PBIAdminUPN,$Security)

Connect-PowerBIServiceAccount -Credential $Credential

$StartDate = Get-Date
$StartDate = $StartDate.AddDays(-1)

$StartDateYearStr  = $StartDate.ToString('yyyy')
$StartDateMonthStr = $StartDate.ToString('MM')
$StartDateDayStr   = $StartDate.ToString('dd')

$StartLogDate = $StartDateYearStr + '-' + $StartDateMonthStr + '-' + $StartDateDayStr + 'T00:00:00.000'
$EndLogDate   = $StartDateYearStr + '-' + $StartDateMonthStr + '-' + $StartDateDayStr + 'T23:59:59.999'


$serverName                  = "MIRAC            "
$databaseName                = "PowerBIServiceLog"
$tableName                   = "UserActivityLog"
$Connection                  = New-Object System.Data.SQLClient.SQLConnection
$Connection.ConnectionString = "server='$serverName';database='$databaseName';trusted_connection=true;"
$Connection.Open()
$Command                     = New-Object System.Data.SQLClient.SQLCommand
$Command.Connection          = $Connection


$ActivityLogs = Get-PowerBIActivityEvent -StartDateTime $StartLogDate -EndDateTime $EndLogDate | ConvertFrom-Json
$MaxValue     = $ActivityLogs.Count


for($i = 0; $i -lt $MaxValue; $i++)
{
        foreach($item in $ActivityLogs[$i]){
                $Id=$item.Id
                $UserType=$item.UserType
                $UserKey=$item.UserKey
                $Workload=$item.Workload
                $UserId=$item.UserId
                $Activity=$item.Activity
                $ItemName=$item.ItemName
                $CreationTime=$item.CreationTime
                $CreationTimeUTC=$item.CreationTimeUTC
                $RecordType=$item.RecordType
                $Operation=$item.Operation
                $OrganizationId=$item.OrganizationId
                $ClientIP=$item.ClientIP
                $UserAgent=$item.UserAgent
                $WorkSpaceName=$item.WorkSpaceName
                $DashboardName=$item.DashboardName
                $DatasetName=$item.DatasetName
                $ReportName=$item.ReportName
                $WorkspaceId=$item.WorkspaceId
                $ObjectId=$item.ObjectId
                $DashboardId=$item.DashboardId
                $DatasetId=$item.DatasetId
                $OrgAppPermission=$item.OrgAppPermission
                $CapacityId=$item.CapacityId
                $CapacityName=$item.CapacityName
                $AppName=$item.AppName
                $IsSuccess=$item.IsSuccess
                $ReportType=$item.ReportType
                $ReportId=$item.ReportId
                $RequestId=$item.RequestId
                $ActivityId=$item.ActivityId
                $AppReportId=$item.AppReportId
                $DistributionMethod=$item.DistributionMethod
                $ConsumptionMethod=$item.ConsumptionMethod

      $insertquery="
      INSERT INTO $tableName
          (
           [Id],
           [UserType],
           [UserKey],
           [Workload],
           [UserId],
           [Activity],
           [ItemName],
           [CreationTime],
           [CreationTimeUTC],
           [RecordType],
           [Operation],
           [OrganizationId],
           [ClientIP],
           [UserAgent],
           [WorkSpaceName],
           [DashboardName],
           [DatasetName],
           [ReportName],
           [WorkspaceId],
           [ObjectId],
           [DashboardId],
           [DatasetId],
           [OrgAppPermission],
           [CapacityId],
           [CapacityName],
           [AppName],
           [IsSuccess],
           [ReportType],
           [ReportId],
           [RequestId],
           [ActivityId],
           [AppReportId],
           [DistributionMethod],
           [ConsumptionMethod]
          )
        VALUES
          (
            '$Id',
            '$UserType',
            '$UserKey',
            '$Workload',
            '$UserId',
            '$Activity',
            '$ItemName',
            '$CreationTime',
            '$CreationTimeUTC',
            '$RecordType',
            '$Operation',
            '$OrganizationId',
            '$ClientIP',
            '$UserAgent',
            '$WorkSpaceName',
            '$DashboardName',
            '$DatasetName',
            '$ReportName',
            '$WorkspaceId',
            '$ObjectId',
            '$DashboardId',
            '$DatasetId',
            '$OrgAppPermission',
            '$CapacityId',
            '$CapacityName',
            '$AppName',
            '$IsSuccess',
            '$ReportType',
            '$ReportId',
            '$RequestId',
            '$ActivityId',
            '$AppReportId',
            '$DistributionMethod',
            '$ConsumptionMethod'
           )"
      $Command.CommandText = $insertquery
      $Command.ExecuteNonQuery()
    }
}
    $Connection.Close();

kod yapısına ulaşacağız.

Herşey hazır olduğuna göre ana PowerShell kod ekranımıza dönüp ilgili kodumuzu çalıştıralım;

power bi powershell user audit service insert data mssql table

Tekrardan herbir log kaydı için 1’lerin olduğu bir çıktı görüntülüyoruz.
Peki MsSQL üzerindeki tablomuza dönecek olursak;

power bi powershell user log audit mssql view

mevcut kullanıcı log bilgilerinin kayıt altına alınmış olduğunu görüntülüyoruz.
Burada unutulmaması gereken ise bir önceki güne döndüğümüzdür.
Bu formatı bir System Task (Sistem Görevi) üzerinde periyordik olarak (Günlük gibi.) çalıştırdığınızda hep bir gün öncesine ait kayıt bilgilerini sisteme aktarıyor olacaktır.
*İlgili format gün içerisinde çalıştırılırsa; ilgili değerlerin silinmesi gerekecektedir, aksi halde sistem üzerinde çift kayıt bilgisi problemi oluşacaktır.

Bugün; PowerShell üzerinde Power BI organizasyon kullanıcı listesi ve kullanıcı hareket dökümlerine yönelik bilgilere ulaşmaya çalıştık.

Bir sonraki PowerShell yazımızda/yazılarımızda;

  • Hata Çıktıları,
  • Veri Kaynağı İşlem Geçmişleri,
  • Öğelerin Dışarı Aktarılması,
  • İçerik Bilgilerinin Dışarı Aktarılması/Kaynağa Yazılması,
  • Veri Kaynağı Yenilemesi

gibi başlıkları ele alıp, ek işlemlerde bulunuyor olacağız.

Tüm işlemlere yönelik kod dökümünü;
https://github.com/miracozturk17/PowerShellQueryChallenge
bağlantısı üzerinden elde edebilirsiniz.

Gelecek yazılarda görüşmek üzere.

İyi çalışmalar…

, ,

İlgili Yazılar