Scripting Games 2010. Advanced Event 7 (Creating a Graphical Tool)

Седьмое задание:

Event Scenario

You have been tasked to create a graphical tool that will display the following information:
1.     Logged-on user name.
2.     Computer name and domain name, if applicable.
3.     How long the user has been logged on.
4.     The number of programs running.
5.     The amount of committed memory and free physical memory.
6.     The current level of CPU utilization.
7.     If the user is a regular user or has administrator rights



 

Design points

·         Your script can be written in any fashion you wish. In VBScript, you may wish to create an HTA; in Windows PowerShell, you may wish to use the WPF from the Windows 7 Resource Kit, PowerShell PowerBoots from CodePlex, PrimalForms from SAPIEN, or any other graphical interface creation tool (or hand-coded .NET).

·         Your script does not need to retrieve remotely, but extra points will be given if it does.

·         Your script does not need to refresh the data, but if you wish to implement a Refresh button, extra points will be granted.

·         Extra design points will be given if you add additional useful information to the script/graphical tool.

Для генерации кода, отвечающего за различные GUI формы и элементы управления я использовал PrimalForms from SAPIEN, очень приятная программа – рекомендую.

Все остальное – достаточно очевидно. Единственный тонкий момент – это определение аптайма пользователя. Я использовал для этого следующую конструкцию:

$LastLogonWMI=(gwmi Win32_NetworkLoginProfile -Filter "Name='$UserDomain\\$UserName'").LastLogon

Не уверен, что это правильно, иногда Win32_NetworkLoginProfile возвращает весьма странные результаты, впрочем, так же, как и следующий способ:

[System.Reflection.Assembly]::LoadWithPartialName("System.DirectoryServices.AccountManagement")
[System.DirectoryServices.AccountManagement.UserPrincipal]::Current.LastLogon.ToLocalTime()

Наверное, самым правильным способом определения времени последнего логона пользователя был бы поиск соответствующих событий в event log’е, но парсить лог было категорически лень, посему остановился на первом варианте.

Результат здесь:

<#
   Show-UserCompProp.ps1 PowerShell shs 20100508
  .Synopsis
   Show some user and computer properties on GUI Form
     Show-UserCompProp.ps1
    .Example
   Show-UserCompProp.ps1
#>
########################################################################
# Fuction returns true if curent user have rights of Local Administrator
#
Function Test-AdminRights {
   ##Well-known SID of Local Administartors group
   $LocAdminsGroupSID='S-1-5-32-544'
   #Get Groups in which current user is the memeber
   $UserGroups=[System.Security.Principal.WindowsIdentity]::GetCurrent().Groups
   #result value
   $IsAdmin=$false
   #parse user groups SID's
   switch ($UserGroups) {
       #if group is Local Administrators group
       #set result value to true
       $LocAdminsGroupSID {$IsAdmin=$true;break}
   }
   #return result
   $IsAdmin
}
########################################################################
# Function returns User Last Logon Time
#

Function Get-UserLastLogon ($UserDomain,$UserName) {
   $Filter="Name='$UserDomain\\$UserName'"
   Write-Verbose "Filter=$Filter"
   $LastLogonWMI=(gwmi Win32_NetworkLoginProfile -Filter "Name='$UserDomain\\$UserName'").LastLogon
   [System.Management.ManagementDateTimeConverter]::ToDateTime($LastLogonWMI)
}
########################################################################
# Function returns Number of Processes owned by the user
#
Function Get-UsersProcessesNum ($UserName) {
   (gwmi Win32_Process | ?{$_.getOwner().user -eq $UserName}).count
}
########################################################################
# Function returns Free Physical Memory
#
Function Get-FreePhysicalMemory {
   (gwmi Win32_OperatingSystem).FreePhysicalMemory
}
########################################################################
# Function returns Commited Memory
#
Function Get-CommitedMemory {
   (Get-WmiObject Win32_PerfFormattedData_PerfOS_Memory).CommittedBytes
}
########################################################################
# Function returns CPU Utilization
#
Function Get-CPUUtilization {
   $i=0
   $SumCPUUtilization=0
   #get sum of load for all processors
   gwmi Win32_Processor|foreach{$i+=1;$SumCPUUtilization+=$_.LoadPercentage}
   #get average load
   $AverageCPUutilization=$SumCPUUtilization/$i
   #return result
   $AverageCPUutilization
}
#
#
#
#
########################################################################
#Generated Form Function
function GenerateForm {
########################################################################
# Code Generated By: SAPIEN Technologies PrimalForms (Community Edition) v1.0.8.0
# Generated On: 07.05.2010 17:23
# Generated By: shs
########################################################################

#region Import the Assemblies
[reflection.assembly]::loadwithpartialname("System.Windows.Forms") | Out-Null
[reflection.assembly]::loadwithpartialname("System.Drawing") | Out-Null
#endregion

#region Generated Form Objects
$frmMain = New-Object System.Windows.Forms.Form
$btnExit = New-Object System.Windows.Forms.Button
$rtbReport = New-Object System.Windows.Forms.RichTextBox
$btnRefresh = New-Object System.Windows.Forms.Button
$InitialFormWindowState = New-Object System.Windows.Forms.FormWindowState
#endregion Generated Form Objects

#----------------------------------------------
#Generated Event Script Blocks
#----------------------------------------------
#Provide Custom Code for events specified in PrimalForms.
$handler_btnRefresh_Click=
{
#Get User and  Computer properties
   $WSHNetwork = New-Object -ComObject WScript.Network
   $ComputerName=$WSHNetwork.ComputerName
   $UserName=$WSHNetwork.UserName
   $UserDomain=$WSHNetwork.UserDomain
   $rtbReport.Text = "ComputerName`t`t:`t$ComputerName`n"
   $rtbReport.Text += "User Name`t`t:`t$UserName`n"
   $rtbReport.Text += "User Domain`t`t:`t$UserDomain`n"
   $rtbReport.Text += "User have admin rights`t:`t"
   $rtbReport.Text += Test-AdminRights
   $rtbReport.Text += "`nUser's last logon time`t:`t"
   $UserLastLogon = Get-UserLastLogon $UserDomain $UserName
   $rtbReport.Text += $UserLastLogon
   $rtbReport.Text += "`nUser Uptime`t`t:`t"+$((get-date)- $UserLastLogon)
   $rtbReport.Text += "`nNumber of user's processes `t:`t"
   $rtbReport.Text += Get-UsersProcessesNum $UserName
   $rtbReport.Text += "`nFree Physical Memory`t:`t"
   $rtbReport.Text += [string](Get-FreePhysicalMemory) + " KB"
   $rtbReport.Text += "`nCommited Memory`t`t:`t"
   $rtbReport.Text += [string]((Get-CommitedMemory)/1kb) +" KB"
   $rtbReport.Text += "`nCPU Utilization`t`t:`t"
   $rtbReport.Text += [string](Get-CPUUtilization) + " %"
}

$handler_btnExit_Click=
{
#TODO: Place custom script here
   $frmMain.close()
}

$OnLoadForm_StateCorrection=
{#Correct the initial state of the form to prevent the .Net maximized form issue
   $frmMain.WindowState = $InitialFormWindowState
}

#----------------------------------------------
#region Generated Form Code
$frmMain.Text = "Some User and Computer properties"
$frmMain.Name = "frmMain"
$frmMain.DataBindings.DefaultDataSourceUpdateMode = 0
$System_Drawing_Size = New-Object System.Drawing.Size
$System_Drawing_Size.Width = 715
$System_Drawing_Size.Height = 536
$frmMain.ClientSize = $System_Drawing_Size

$btnExit.TabIndex = 2
$btnExit.Name = "btnExit"
$System_Drawing_Size = New-Object System.Drawing.Size
$System_Drawing_Size.Width = 75
$System_Drawing_Size.Height = 23
$btnExit.Size = $System_Drawing_Size
$btnExit.UseVisualStyleBackColor = $True

$btnExit.Text = "Exit"

$System_Drawing_Point = New-Object System.Drawing.Point
$System_Drawing_Point.X = 585
$System_Drawing_Point.Y = 451
$btnExit.Location = $System_Drawing_Point
$btnExit.DataBindings.DefaultDataSourceUpdateMode = 0
$btnExit.add_Click($handler_btnExit_Click)

$frmMain.Controls.Add($btnExit)

$rtbReport.Name = "rtbReport"
$rtbReport.ReadOnly = $True
$rtbReport.Text = "Press Refresh button"
$rtbReport.DataBindings.DefaultDataSourceUpdateMode = 0
$System_Drawing_Point = New-Object System.Drawing.Point
$System_Drawing_Point.X = 55
$System_Drawing_Point.Y = 25
$rtbReport.Location = $System_Drawing_Point
$System_Drawing_Size = New-Object System.Drawing.Size
$System_Drawing_Size.Width = 391
$System_Drawing_Size.Height = 449
$rtbReport.Size = $System_Drawing_Size
$rtbReport.TabIndex = 1

$frmMain.Controls.Add($rtbReport)

$btnRefresh.TabIndex = 0
$btnRefresh.Name = "btnRefresh"
$System_Drawing_Size = New-Object System.Drawing.Size
$System_Drawing_Size.Width = 75
$System_Drawing_Size.Height = 23
$btnRefresh.Size = $System_Drawing_Size
$btnRefresh.UseVisualStyleBackColor = $True

$btnRefresh.Text = "Refresh"

$System_Drawing_Point = New-Object System.Drawing.Point
$System_Drawing_Point.X = 585
$System_Drawing_Point.Y = 25
$btnRefresh.Location = $System_Drawing_Point
$btnRefresh.DataBindings.DefaultDataSourceUpdateMode = 0
$btnRefresh.add_Click($handler_btnRefresh_Click)

$frmMain.Controls.Add($btnRefresh)

#endregion Generated Form Code

#Save the initial state of the form
$InitialFormWindowState = $frmMain.WindowState
#Init the OnLoad event to correct the initial state of the form
$frmMain.add_Load($OnLoadForm_StateCorrection)
#Show the Form
$frmMain.ShowDialog()| Out-Null

} #End Function
#
#==================================== Script entry point ====================
#Call the Function
GenerateForm 

Leave a Reply

Your email address will not be published. Required fields are marked *

Notify me of followup comments via e-mail. You can also subscribe without commenting.