Feeds:
Записи
Комментарии

Archive for Апрель 2011

Скажем есть некое приложение,которое пишет информацию в потом Output,из которого нам надо считать и если есть определенная строка ,произвести какое-либо действие.Для этого нам потребуется класс Process и ProcessStartInfo.Разберем на примере программы ping.В данном примере мы лишь будем читать из потока и выводить асинхронно на консоль данные.

#Задает набор значений, используемых при запуске процесса.
$info = New-Object System.Diagnostics.ProcessStartInfo -Property @{
			"FileName" = "ping.exe"
			"Arguments" = "-t 127.0.0.1"
			"UseShellExecute" = $false
			"RedirectStandardOutput" = $true
			}
#Создаем объект типа Process
$pr = New-Object System.Diagnostics.Process
#Присваиваем свойству StartInfo набор значений из объекта $info
$pr.StartInfo = $info

#Создаем событие,которое будет реагировать,есть ли данные в потоке Output и выводим в консоль
Register-ObjectEvent -InputObject $pr -EventName OutputDataReceived -action {Write-Host $Event.SourceEventArgs.Data}
#Запускаем процесс с предопределенными параметрами
$pr.start()
#Начинает операции асинхронного считывания в перенаправленном потоке StandardOutput приложения.
$pr.BeginOutputReadLine()

Вывод —  пингуем сайт google.ru и отбираем сообщения с временем задержки 60-79мс.

Register-ObjectEvent -InputObject $pr -EventName OutputDataReceived -action {
if ($Event.SourceEventArgs.Data -match "time=[67][0-9]")
	{
	Write-Host $Event.SourceEventArgs.Data
	}
}

Reply from 74.125.79.147: bytes=32 time=64ms TTL=249
Reply from 74.125.79.147: bytes=32 time=64ms TTL=249
Reply from 74.125.79.147: bytes=32 time=64ms TTL=249
Reply from 74.125.79.147: bytes=32 time=64ms TTL=249
Реклама

Read Full Post »

Для отображение elevated иконки на нашей форме ,придется задействовать WinAPi функции,так как каких либо методов для достижения результата с использование .NET ,у нас нет.Для C++ существует несколько методов  Button_SetElevationRequiredStateBCM_SETSHIELD.  Button_SetElevationRequiredState — является макросом ,поэтому можно посмотреть ,что он делает в заголовочном фале Commctrl.h.

	Header  Commctrl.h
	#define BCM_FIRST               0x1600      // Button control messages
	#if _WIN32_WINNT >= 0x0600
	// Macro to use on a button or command link to display an elevated icon
	#define BCM_SETSHIELD            (BCM_FIRST + 0x000C)
	#define Button_SetElevationRequiredState(hwnd, fRequired) \
	    (LRESULT)SNDMSG((hwnd), BCM_SETSHIELD, 0, (LPARAM)fRequired)
	#endif /* _WIN32_WINNT >= 0x0600 */

Этот метод вызывает функцию SendMessage,которой мы и воспользуемся.Как объявлять функцию
SendMessage для .Net,можно посмотреть — http://www.pinvoke.net/default.aspx/user32.sendmessage
Приведу простой пример формы с одной кнопкой,для запуска процесса PowerShell c повышенными привилегиями.

#обычная кнопка
$BCM_FIRST = 0x1600
#кнопка со щитом
$BCM_SETSHIELD  = $BCM_FIRST + 0x000C

#входит ли пользователь в группу администраторы
function isAdmin {
	$identity = [System.Security.Principal.WindowsIdentity]::GetCurrent()
  	$principal = new-object System.Security.Principal.WindowsPrincipal($identity)
  	$principal.IsInRole([Security.Principal.WindowsBuiltInRole]::Administrator)
}

#поднимаем уровень привилегий
function RunElevated
{
    try {
    (Start-Process powershell -Verb RunAs -ErrorAction Stop -PassThru).WaitForExit()
    }
    catch {[System.Windows.Forms.MessageBox]::Show("Failed to elevate process.")}
}

#отображаем кнопку со щитом
function DisplayIcon
{
	$signature = @"
	 [DllImport("User32.DLL")]
    public static extern int SendMessage(IntPtr hWnd, UInt32 Msg, Int32 wParam, Int32 lParam);
"@
	$type = Add-Type -MemberDefinition $signature `
	-Name Win32 -Namespace SendMessage `
	-PassThru
	$type::SendMessage($($button1.handle),$BCM_SETSHIELD,0,1)
}

[reflection.assembly]::loadwithpartialname("System.Windows.Forms") | Out-Null
[reflection.assembly]::loadwithpartialname("System.Drawing") | Out-Null

$form1 = New-Object System.Windows.Forms.Form
$button1 = New-Object System.Windows.Forms.Button

$form1.Text = "Shield Form"
$form1.ClientSize = New-Object System.Drawing.Size(202,81)
$form1.FormBorderStyle = "FixedDialog"
$form1.MaximizeBox = $false
$form1.MinimizeBox = $false

$button1.TabIndex = 0
$button1.Size =  New-Object System.Drawing.Size(75,23)
$button1.Text = "Elevate"
$button1.UseVisualStyleBackColor = $true
$button1.Location = New-Object System.Drawing.Point(63,21)
$button1.add_Click({RunElevated})

$form1.Controls.Add($button1)
$form1.Add_Load({
	#проверяем входит ли пользователь в группу администраторы,если нет,то отображаем кнопку со щитом
	if (!$(isAdmin)) {
	$button1.FlatStyle = [System.Windows.Forms.FlatStyle]::System
	DisplayIcon
	}
})
[System.Windows.Forms.Application]::EnableVisualStyles()
[System.Windows.Forms.Application]::Run($form1)

Uploaded with ImageShack.us

Read Full Post »

Больше всего нас будет интересовать записи типа A .Для получения всех записей типа A можно воспользоваться WMI и классом  “MicrosoftDNS_AType”.  Это способ работает, как для зон, интегрированных в Active Directory,так и нет.

Приведу пару примеров:

1)      Перечислим все записи типа А;

Get-WmiObject MicrosoftDNS_AType -NameSpace 'Root\MicrosoftDNS'

2)      Перечислим все записи типа A из зоны — contoso.com;

Get-WmiObject MicrosoftDNS_AType -NameSpace 'Root\MicrosoftDNS' -Filter "ContainerName='contoso.com'"

Для более подробного ознакомления, читайте в MSDN  — Domain Name System. Для PowerShell ,есть модуль dnsshell,который основан на WMI. Всем кто интересуется или работает с DNS,советую обязательно ознакомиться не только с модулем, но и исходными кодами.

К сожалению, класс “MicrosoftDNS_AType” ,не дает нам возможности отобразить ACL для записей. Для решения, нам поможет  .NET и класс System.DirectoryServices.DirectoryEntry,который представлен в PowerShell в более удобной форме (акселераторе [ADSI]).

Для отображение DNS записей в Active Directory, можно воспользоваться оснасткой ADSIEdit.msc,т.к Aduc.msc,нам такой возможности не дает. По умолчанию DNS зоны не отображаются в ADSIEdit,поэтому мы  должны их загрузить. Вид запроса должен быть:

DC=contoso.com,CN=MicrosoftDNS,DC =DomainDnsZones,DC=contoso,DC=com

DC=contoso.com,CN=MicrosoftDNS,DC =ForestDnsZones,DC=contoso,DC=com

1)      Перечислим все записи типа A в зоне contoso.com;

[ADSI]"LDAP://DC=contoso.com,CN=MicrosoftDNS,DC=DomainDnsZones,DC=contoso,DC=com" | `
	Foreach {$_.Children }  | Select -ExpandProperty Name

2)      Отобразим ACL для записи  типа A с именем DC;

$record = [ADSI]"LDAP://DC=DC,DC=contoso.com,CN=MicrosoftDNS,DC =DomainDnsZones,DC=contoso,DC=com"
$record.objectSecurity.Access

3)      Отобразим ACL для записи  типа A с именем DC с использованием QuestAD;

Get-QADObject -Identity "DC=DC,dc=contoso.com,cn=MicrosoftDns,dc=DomainDnsZones,dc=contoso,dc=com" | `
Get-QADPermission -Inherited -SchemaDefault

4)      Более сложный метод получения ACL через свойство nTSecurityDescriptor;

$record = [ADSI]"LDAP://DC=DC,DC=contoso.com,CN=MicrosoftDNS,DC =DomainDnsZones,DC=contoso,DC=com"
#Используем свойство nTSecurityDescriptor
$sd = $record.nTSecurityDescriptor | Foreach {$_.gettype().invokemember("DiscretionaryAcl","GetProperty",$null,$_,$null)}
#Перечисляем все ACE для объекта и его свойства.
$sd | foreach { New-Object PsObject  @{
				"Trustee" = $_.gettype().invokemember("Trustee","GetProperty",$null,$_,$null)
				"AceFlags" = $_.gettype().invokemember("AceFlags","GetProperty",$null,$_,$null)
				"AceType" = $_.gettype().invokemember("AceType","GetProperty",$null,$_,$null)
				"Flags" = $_.gettype().invokemember("Flags","GetProperty",$null,$_,$null)
				"ObjectType" = $_.gettype().invokemember("ObjectType","GetProperty",$null,$_,$null)
				"InheritedObjectType" = $_.gettype().invokemember("InheritedObjectType","GetProperty",$null,$_,$null)
				"AccessMask" = $_.gettype().invokemember("AccessMask","GetProperty",$null,$_,$null)
				}
			}

Read Full Post »