Dnešní příspěvek je opravdu dlouhý, ale ve skutečnosti popisuje vcelku jednoduchou věc - PowerShellový skript pro snadné získání seznamu přihlášených uživatelů.
Taková informace je při údržbě AX prostředí potřeba dost často, pokud chcete brát ohledy na přihlášené uživatele a nevypínat jim služby pod rukama. Lze se samozřejmě přihlásit do AX, otevřít modul Administrace, formulář Uživatelé online a tam ověřit, zda je někdo přihlášený. To ale dost zdržuje a tak jsem si tento úkol trochu zjednodušil skriptem, který umožní zvolit konfigurační soubor Dynamics AX, připojí se pomocí Business Connectoru a vypíše přihlášené uživatele do konzolového okna.
Trochu blíže k předpokladům pro tento skript:
- Konfigurační soubory (.axc) pro všechna prostředí jsou uložena v jednom adresáři (viz proměnnou $configurationPath) a týkají se Dynamics AX 2009. V tomto ohledu jsem jen využil existující systém v naší firmě, vy si možná budete muset skript upravit.
- Nainstalovaný Business Connector
- PowerShell 2.0
- .NET 3.0+ (kvůli WPF)
První skript příjmá jako parametr (
$args[0]) jméno konfiguračního souboru. Načte sestavení BussinessConnectorNet.dll, vytvoří objekt typu Axapta a zaloguje se pomocí konfiguračního souboru (v něm je adresa AOS atd.). V dalším kroku se dotáže na uživatelská připojení (tabulka SysClientSessions), popř. další informace o uživateli a AOS. Tyto informace zabalí do objektu (což usnadňuje další zpracování) a ten předá na výstup. Ukázka výsledku:
Zdrojový kód vypadá takto (některé řádky byly kvůli přehlednosti zalomeny):
$connectorDllPath = 'C:\Program Files\Microsoft Dynamics AX\50\' `
+ 'Client\Bin\Microsoft.Dynamics.BusinessConnectorNet.dll'
$configurationPath = 'D:\CONFIGURATIONS'
$configurationName = $args[0]
$configFile = Join-Path $configurationPath $configurationName
if (!(Test-Path $configFile))
{
throw "Konfigurace $configFile nebyla nalezena"
}
#zalogování do AX pomocí Business Connectoru
try
{
[void][reflection.Assembly]::Loadfile(
$connectorDllPath
)
$ax = New-Object Microsoft.Dynamics.BusinessConnectorNet.Axapta
$ax.logon('', '', '', $configFile)
}
catch
{
throw 'Přihlášení pomocí Business Connectoru se nezdařilo'
}
#objekty představující AX tabulky
$sysClientSessions = $ax.CreateAxaptaRecord('SysClientSessions');
$sysServerSessions = $ax.CreateAxaptaRecord('SysServerSessions');
#dotaz na aktivní uživatele přihlášené přes GUI
$sysClientSessions.ExecuteStmt('select * from %1 where %1.Status == 1 ' `
+ '&& %1.ClientType == 0');
if (!$sysClientSessions.Found)
{
'0 aktivních uživatelů'
}
#iterace přes uživatele, získaní podrobných informací a zabalení do objektu
while ($sysClientSessions.Found)
{
$userId = $sysClientSessions.get_Field('UserId')
$userName = $ax.CallStaticClassMethod('UserInfoHelp', 'userName', $userId)
$sysServerSessions.ExecuteStmt('select * from %1 where %1.ServerId == ' `
+ $sysClientSessions.get_Field('ServerId'))
$aosInstanceName = $sysServerSessions.get_Field('AOSId')
#
zabalení do objektu
New-Object PSObject -Property @{
AosName = $aosInstanceName
UserId = $userId
UserName = $userName}
[void]$sysClientSessions.Next();
}
#odhlášení z AX
[void]$ax.logoff()
Druhý skript slouží k výběru konfigurace AX a jméno této konfigurace předává prvnímu skriptu. Seznam konfigurací je zobrazen v grafickém okně, protože kliknutí mi přišlo jako nejrychlejší způsob výběru. GUI je vytvořeno pomocí WPF (Windows Presentation Foundation) a vypadá takto (s tím rozdílem, že já tam mám konfigurací celkem 42):
Seznam konfigurací je naplněn pomocí příkazu
Get-ChildItem
(alias
dir
).
Zvolená konfigurace
(
$listBox.SelectedItem
) je použita jako parametr pro výše uvedený skript a daný kód je umístěn v obsluze kliknutí na tlačítko (
$button.add_Click()
).
$configurationPath = 'D:\CONFIGURATIONS'
Add-Type –assemblyName PresentationFramework
Add-Type –assemblyName PresentationCore
Add-Type –assemblyName WindowsBase
$window = New-Object Windows.Window
$window.Title = 'AX konfigurace'
$window.SizeToContent = 'WidthAndHeight'
$label = New-Object Windows.Controls.Label
$label.Content = 'Seznam konfigurací:'
$listBox = New-Object Windows.Controls.Listbox
$listBox.ItemsSource = (% {
Get-ChildItem
$configurationPath -Include *.axc -Name})
$button = New-Object Windows.Controls.Button
$button.Content = 'Zobraz přihlášené uživatele'
$button.add_Click(
{
if ($listBox.SelectedItem)
{
$window.Hide()
Write-Host
$listBox.SelectedItem
try
{
#volání samostatného skriptu na získání informace o uživatelích
$activeUsers = (absolutníCesta\prvníSkript.ps1 $listBox.SelectedItem)
}
catch
{
Write-Host
$error
[0] -ForegroundColor Red
exit
}
}
})
$stackPanel = New-Object Windows.Controls.Sta
ckPanel
$stackPanel.Orientation = 'Vertical'
[void]
$stackPanel.Children.Add($
label
)
[void]
$stackPanel.Children.Add(
$listbox
)
[void]
$stackPanel.Children.Add(
$button
)
$window.Content = $stackPanel
[void]
$window.ShowDialog()
$textbox.Text
$activeUsers
Protože WPF okno vyžaduje běh v STA módu (Single-Threaded Apartment; neznám smysluplný překlad), nelze tento skript spustit běžným způsob. Jednou (a nejjednoduší) možností je zavolání PowerShellu s parametrem -STA, takže spuštěcí příkaz lze napsat (a uložit do .lnk) třeba takto:
C:\WINDOWS\system32\WindowsPowerShell\v1.0\powershell.exe
-STA
-noexit
-command cesta\jmenoSkriptu.ps1
a kam zmizel Howard Wolowitz? :)
OdpovědětVymazat