ShS's Blog

Just another sysadmin's weblog

Scripting Games 2010. Advanced Event 9 (Logging Out Users Forcibly Based on a Program’s Launch)

Posted by shs на 2010/05/26

Девятое задание:

Event Scenario

Your users do not seem to know how to log out of their computers. This is a problem because each evening, a particular application runs as a scheduled task to back itself up to a network share. This occurs before the network backup job takes place. The storage manager has assigned you to write a script that will forcibly log out users from their workstations when a particular program launches. For the purposes of this example, use calc.exe.

Design Points

·         When you manually launch calc.exe on the workstation, it should log you out.
·         The actual name of the program that launches should be configurable from the command line when your script is run (the script should be able to monitor for the name of any executable).
·         Via a dialog box or other graphical device, your script should prompt the user that the workstation will log them out within 60 seconds.
·         Design points for creating a force mode and a “nice mode.” The nice mode should check to see if any Word documents or Excel spreadsheets are open. If they are, your script should not log the user out at that time. The script should check back every five minutes to see if the documents or spreadsheets are still open.

 

Эта задачка очень похожа на 6ю (Scripting Games 2010. Advanced Event 6)

Соответственно и решение аналогичное:
Регистрируем в системе подписчик на событие (в данном случае подписываемся на событие запуска определенного процесса)
Ждем наступления события и помещения в  его в очередь событий.
При наступлении события выполняем ряд проверок и, если ситуация соответствует заданным условиям, выполняем force logoff пользователя.

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

<#
  	LogOff-UserOnEvent.ps1 PowerShell shs 20100511
  	
.Synopsis
   	Log off current user during the launch of a given process
   
    LogOff-UserOnEvent.ps1 [ProcessName] [-Force] [-Help]

.Parameter ProcessName
	Name of process that will be wating for starting of user logoff
	
.Parameter switch Force
	User logoff will be forced
	
.Parameter switch Help
	Show help message

.Examples
   	LogOff-UserOnEvent.ps1 -Help
	LogOff-UserOnEvent.ps1 -ProcessName Notepad -Force
   
#>
param ($ProcessName="calc.exe", [switch]$Force, [switch]$Help)
#########################################################################################################
#
#    Function Clean-Event
#    Remove event with EventSourceID from event queue and
#    unregister all event subscriberes for event with this EventSourceID
#
#.Parameter $EventSourceID
#    Event Source Identifier
#
Function Clean-Event ($EventSourceID) {
  #Clean event queue from events with $EventSourceID
  Get-Event -SourceIdentifier $EventSourceID -ErrorAction SilentlyContinue| Remove-Event
  #Unregister event with $MyQuery
  get-eventsubscriber -force| ?{ $_.SourceIdentifier -eq $EventSourceID}| unregister-event -force
}
#########################################################################################################
#
# Function Show-Help. Write  first blok comment of this script to the host
#
Function Show-Help ($ScriptFullName){
   if ($ScriptFullName) {
       $IsHelpLine=$false
       switch -file $ScriptFullName {
           {$_ -match "<#"}     {Write-Host $_;$IsHelpLine=$true;continue}
           {$_ -match "#>"}     {Write-Host $_;$IsHelpLine=$false;break}
           {$IsHelpLine}        {Write-Host $_;}
       }
   }
}
#---------------------------------------------------------------------------------------------------------
#Generated Form Function
function GenerateForm {
########################################################################
# Code Generated By: SAPIEN Technologies PrimalForms (Community Edition) v1.0.8.0
# Generated On: 10.05.2010 15:49
# Generated By: __
########################################################################

#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
$lblMsg = New-Object System.Windows.Forms.Label
$timer1 = New-Object System.Windows.Forms.Timer
$InitialFormWindowState = New-Object System.Windows.Forms.FormWindowState
#endregion Generated Form Objects

#----------------------------------------------
#Generated Event Script Blocks
#----------------------------------------------
#Provide Custom Code for events specified in PrimalForms.
$handler_timer1_Tick= 
{
#if 60 sex is not up...
	if ($CountDownTimes -gt 0) {
		$CountDownTimes-=1
		$lblMsg.Text = "User will be logged off in $CountDownTimes second(s)"
		#$CountDown
	}
#if 60 sec is up...
	else {
		#set new timer interval - 5 min
		$timer1.Interval = $TimerInterval_2
		#if excel or winword are running and script is not running in Force mode
		if ((@(Get-Process|where{$_.name -match "excel|winword"}).count -gt 0) -and !$Force) {
			#
			$lblMsg.Text = "Close excel and/or winword application!"
		}
		else {
			$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.TopMost = $True
$frmMain.Text = "WarningMessage"
$frmMain.Name = "frmMain"
$frmMain.ControlBox = $False
$frmMain.DataBindings.DefaultDataSourceUpdateMode = 0
$System_Drawing_Size = New-Object System.Drawing.Size
$System_Drawing_Size.Width = 395
$System_Drawing_Size.Height = 133
$frmMain.ClientSize = $System_Drawing_Size
$frmMain.FormBorderStyle = 1

$lblMsg.TabIndex = 0
$System_Drawing_Size = New-Object System.Drawing.Size
$System_Drawing_Size.Width = 371
$System_Drawing_Size.Height = 23
$lblMsg.Size = $System_Drawing_Size
$lblMsg.Text = "User will be logged off in $CountDownTimes second(s)"

$System_Drawing_Point = New-Object System.Drawing.Point
$System_Drawing_Point.X = 12
$System_Drawing_Point.Y = 49
$lblMsg.Location = $System_Drawing_Point
$lblMsg.DataBindings.DefaultDataSourceUpdateMode = 0
$lblMsg.Name = "lblMsg"

$frmMain.Controls.Add($lblMsg)

$timer1.Interval = $TimerInterval_1
$timer1.Enabled = $True
$timer1.add_Tick($handler_timer1_Tick)

#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 ================================================
cls
$VerbosePreference="Continue"
#
if (!$Help) {
	#Name for event identifier
	$EventSourceID="Control Process started"
	#To clear session from events with ID =$EventSourceID  and subscribers for these enevts
	Clean-Event $EventSourceID
	#
	#Query for process started
	$ProcStartQuery = "SELECT * FROM __InstanceCreationEvent WITHIN 2 WHERE TargetInstance ISA 'Win32_Process'  AND TargetInstance.Name = '$ProcessName'"
	Write-Verbose "WMI Query -  $ProcStartQuery"
	#
	#Register Event for $MyQuery
	Register-WmiEvent -Query $ProcStartQuery -SourceIdentifier $EventSourceID
	Write-Verbose "WMIEvent watcher registered"
	#
	#
	#Waiting for the events in the events queue
	Write-Verbose "Waiting for the events in the events queue"
	$EventFromQueue = Wait-Event -SourceIdentifier $EventSourceID
	$ProcStartEvent = $EventFromQueue.SourceEventArgs.NewEvent.TargetInstance
	Write-Verbose $ProcStartEvent
	#
	#
	#
	#Set GUI Form constants
	#First timer interval (in miliseconds)
	$TimerInterval_1=1000
	#Second timer interval (in miliseconds)
	$TimerInterval_2=1000*300 #5 min
	#How much times count down first interval
	$CountDownTimes=60
	#
	#Show GUI Form
	Write-Verbose "Starting GUI form..."
	GenerateForm
	#
	#
	#Force LogOff
	Write-Verbose "Logging off user"
	$ForcedLogOff=4
	$OS = gwmi Win32_OperatingSystem
	$OS.Win32Shutdown($ForcedLogOff)|Out-Null
	#
	#Clean Events queue
	Clean-Event $EventSourceID
}
else {
	#Write top block comment as help
	Show-Help $MyInvocation.MyCommand.Path
}
Реклама

Добавить комментарий

Заполните поля или щелкните по значку, чтобы оставить свой комментарий:

Логотип WordPress.com

Для комментария используется ваша учётная запись WordPress.com. Выход / Изменить )

Фотография Twitter

Для комментария используется ваша учётная запись Twitter. Выход / Изменить )

Фотография Facebook

Для комментария используется ваша учётная запись Facebook. Выход / Изменить )

Google+ photo

Для комментария используется ваша учётная запись Google+. Выход / Изменить )

Connecting to %s

 
%d такие блоггеры, как: