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

Archive for Декабрь 2011

По умолчанию в Windows нет консольного приложения для управления ABE. Более подробно про ABE,можно узнать в блоге Алексея Горбунова и ABE Graphical User Interface , во второй ссылке подробно рассказывается, какие API используются для управления ABE.

Утилита командной строки для управления ABE(более подробно смотри во второй ссылке):

ABECMD — http://www.microsoft.com/download/en/details.aspx?displaylang=en&id=17510

В статье про “управление кэшированием общих папок”, весь функционал скрипта уже был реализован, поэтому достаточно было добавить только флаг FLAGS_ACCESS_BASED_DIRECTORY_ENUM, который равняется 0x0800.

$code = @"
public enum CacheType
{
	Manual    = 0x00,
	Documents = 0x10,
	Programs  = 0x20,
	None      = 0x30,
}

public const int FLAGS_ACCESS_BASED_DIRECTORY_ENUM = 0x0800;

[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)]
public struct SHARE_INFO_1005
{
    public uint shi1005_flags;
}

[DllImport("Netapi32", CharSet=CharSet.Auto)]
    public static extern int NetApiBufferFree(IntPtr Buffer);

[DllImport("Netapi32.dll", SetLastError=true)]
public static extern int NetShareGetInfo(
    [MarshalAs(UnmanagedType.LPWStr)] string serverName,
    [MarshalAs(UnmanagedType.LPWStr)] string netName,
    Int32 level,
    out IntPtr bufPtr );

[DllImport("Netapi32.dll", CharSet = CharSet.Unicode)]
public static extern uint NetShareSetInfo(string servername, string netname,
    uint level, ref SHARE_INFO_1005 buf, out uint paramerror);
"@

Add-Type -MemberDefinition $code -name Share -namespace System

function Get-ShareABE
{
	param(
			[parameter(Mandatory=$true,ValueFromPipeline=$true,
			ValueFromPipelineByPropertyName=$true)]
			[Alias("Name")]
			[string]$ShareName
		)

	process {
		$bufptr = [IntPtr]::Zero
		$return = [Share]::NetShareGetInfo($null,$ShareName,1005,[ref]$bufptr)
		if($return -eq 0)
		{
			$Enable = "Disabled"
			$str1005 = [System.Runtime.InteropServices.Marshal]::PtrToStructure($bufptr,[Share+SHARE_INFO_1005])
			$value = $str1005.shi1005_flags
			if ($value -band [Share]::FLAGS_ACCESS_BASED_DIRECTORY_ENUM)
			{
				$Enable = "Enabled"
			}
			Get-WmiObject Win32_Share -Filter "Name='$ShareName'" | Select-Object Name,`
				Path,Description,@{n="ABE";e={$Enable}},@{n="Flag";e={$value}}
		}
		else
		{
			Write-Host (net helpmsg $return)
		}
		[Share]::NetApiBufferFree($bufptr) | Out-Null
	}
}

function Set-ShareABE
{
	param(
		[parameter(Mandatory=$true,Position=0)]
		[string]$ShareName,
		[parameter(Mandatory=$true,Position=1)]
		[ValidateSet("Enable", "Disable")]
		[string]$Type
	)

	$paramerror = 0

	if ($Type -eq "Disable")
	{
		$flag = (Get-ShareABE -ShareName $ShareName).Flag -bxor [Share]::FLAGS_ACCESS_BASED_DIRECTORY_ENUM
	}
	else
	{
		$flag = [Share]::FLAGS_ACCESS_BASED_DIRECTORY_ENUM
	}
	$buf = New-Object Share+SHARE_INFO_1005 -Property @{shi1005_flags = $flag}
	$return = [Share]::NetShareSetInfo($null,$ShareName,1005,[ref]$buf,[ref]$paramerror)
	if ($return)
	{
		Write-Host (net helpmsg $return)
	}
}

Применение функции Get-ShareABE:

PS > Get-ShareABE doesnotexists
 This shared resource does not exist.
PS > Get-ShareABE Test

Name        : TEST
Path        : C:\TEST
Description :
ABE         : Disabled
Flag        : 0

PS > Get-WmiObject Win32_Share | Get-ShareABE

Name        : ADMIN$
Path        : C:\Windows
Description : Remote Admin
ABE         : Disabled
Flag        : 0

Name        : C$
Path        : C:\
Description : Default share
ABE         : Disabled
Flag        : 0

Name        : IPC$
Path        :
Description : Remote IPC
ABE         : Disabled
Flag        : 0

Name        : TEST
Path        : C:\TEST
Description :
ABE         : Disabled
Flag        : 0

Применение функции Set-ShareABE:

PS > Get-ShareABE Test

Name        : TEST
Path        : C:\TEST
Description :
ABE         : Disabled
Flag        : 0

PS > Set-ShareABE Test -Type Enable
PS > Get-ShareABE Test

Name        : TEST
Path        : C:\TEST
Description :
ABE         : Enabled
Flag        : 2048

PS > Set-ShareABE Test -Type Disable
PS > Get-ShareABE Test

Name        : TEST
Path        : C:\TEST
Description :
ABE         : Disabled
Flag        : 0
Реклама

Read Full Post »

Q&A

1) Как получить номер недели в месяце (1-5)?

Function Get-WeekOfMonth    
{    
    param ([datetime]$date = (Get-Date)) 
    
    $beginningOfMonth = New-Object DateTime($date.Year,$date.Month,1)  
  
    while ($date.Date.AddDays(1).DayOfWeek -ne (Get-Culture).DateTimeFormat.FirstDayOfWeek)
    { 
        $date = $date.AddDays(1)    
    } 
    
    [int]([Math]::Truncate($date.Subtract($beginningOfMonth).TotalDays  / 7) + 1)   
}  

2) Как отключить «X» в консоли PowerShell?

$code = @"
[DllImport("user32.dll")] 
public static extern int DeleteMenu(IntPtr hMenu, int nPosition, int wFlags);
 
[DllImport("User32")]
public static extern IntPtr GetSystemMenu(IntPtr hWnd, bool bRevert);
"@

Add-Type -MemberDefinition $code -Name HideClose -Namespace System

$hMenu = [HideClose]::GetSystemMenu((gps -id $pid).MainWindowHandle, $false)
[HideClose]::DeleteMenu($hMenu,0xF060, 0)

3) Как используя метод XMLDocument.Save() сохранить данные в переменную?

$mem = New-Object IO.MemoryStream
$writer = New-Object IO.StreamWriter($mem)
$xml.Save($writer)
$var = [System.Text.Encoding]::Default.GetString($mem.toarray())
$var

Или
 
$xml.Save(($mem=New-Object IO.MemoryStream))
$var=[System.Text.Encoding]::Default.GetString($mem.toarray())

4) Какой метод класса System.Net.DNS лучше использовать?

Для разрешение имен в прямом и обратном направлении,лучше всего использовать статический метод GetHostEntry(IPAddress) и GetHostEntry(String).

5) Как отключить positional parameters?

V2:
param ($badparam,$i1,$i2)
if ($badparam) {«Вы не ввели обязательные параметры»}

V3: [CmdletBinding(PositionalBinding=$false)]

Read Full Post »

Текущие командлеты, не очень хорошо справляются с данной задачей, поэтому эффективным решением – использовать .Net. На одном из форумов, был найден скрипт на C#, который полностью решал эту задачу. Переводить скрипт полностью на PowerShell, я не вижу смысла, хотя код транслируется очень легко. Оригинал скрипта, можно посмотреть  — http://bit.ly/uR1bUL . Я сделал лишь небольшую обвязку в виде функции.


Function Get-EndTokenFile
{
	<#
	    .SYNOPSIS 
	    Читает последние N строк из файла.

	    .DESCRIPTION
	    Читаем последние N строк из файла с заданной кодировкой(по умолчанию ASCII)
		по заданному пути,который является обязательным параметром.
		
		.PARAMETER Path
		Путь к файлу(полное имя файла).Подстановочные знаки не разрешены.
		
		.PARAMETER Encoding
		Задает тип кодировки, используемой в файле. Пример: "Unicode", "UTF7", "UTF8", 
		"UTF32", "ASCII", "BigEndianUnicode", "Default","OEM","Windows-1251". 
		По умолчанию используется кодировка "ASCII".
		
		.PARAMETER ReadCount
		Количество выводимых строк.По умолчанию используется 1.
		
		.PARAMETER Separator
		Указывает разделитель для строк. По умолчанию используется разделитель `r`n.
		
		.PARAMETER Verbose
		Отображает подробные сведения о действиях, выполняемых командой.
		
		.PARAMETER WhatIf
		Описывает, что произойдет при выполнении команды, без ее фактического выполнения.

	     .EXAMPLE
	     C:\PS> Get-EndTokenFile -Path C:\file.txt
		 
		 .EXAMPLE
	     C:\PS> Get-EndTokenFile -Path C:\file.txt -WhatIf
		 
		 .EXAMPLE
	     C:\PS> Get-EndTokenFile -Path C:\file.txt -ReadCount 2
		 
		 .EXAMPLE
	     C:\PS> Get-EndTokenFile -Path C:\file.txt -Encoding Unicode
		 
		 .EXAMPLE
	     C:\PS> Get-ChildItem C:\Files\*.txt | Get-EndTokenFile 
	#>


	[CmdletBinding(SupportsShouldProcess=$true)]
	param (
			[Parameter(
					Mandatory=$true,
            		ValueFromPipeline=$true,
					ValueFromPipelineByPropertyName=$true
					)]
			[Alias("FullName")]
			[string]
			$Path,
			[string]$Encoding = "ASCII",
			[Int64]$ReadCount = 1,
			[string]$Separator = "`r`n"
		)
			
begin {
$code = @"
public static string ReadEndTokens(string path, Int64 numberOfTokens, Encoding encoding, string tokenSeparator) { 
 
    int sizeOfChar = encoding.GetByteCount("\n"); 
    byte[] buffer = encoding.GetBytes(tokenSeparator); 
 
 
    using (FileStream fs = new FileStream(path, FileMode.Open)) { 
        Int64 tokenCount = 0; 
        Int64 endPosition = fs.Length / sizeOfChar; 
 
        for (Int64 position = sizeOfChar; position < endPosition; position += sizeOfChar) { 
            fs.Seek(-position, SeekOrigin.End); 
            fs.Read(buffer, 0, buffer.Length); 
 
            if (encoding.GetString(buffer) == tokenSeparator) { 
                tokenCount++; 
                if (tokenCount == numberOfTokens) { 
                    byte[] returnBuffer = new byte[fs.Length - fs.Position]; 
                    fs.Read(returnBuffer, 0, returnBuffer.Length); 
                    return encoding.GetString(returnBuffer); 
                } 
            } 
        } 
 
        // handle case where number of tokens in file is less than numberOfTokens 
        fs.Seek(0, SeekOrigin.Begin); 
        buffer = new byte[fs.Length]; 
        fs.Read(buffer, 0, buffer.Length); 
        return encoding.GetString(buffer); 
    } 
} 
"@

	Add-Type -MemberDefinition $code -Name ReadLong -Namespace System -UsingNamespace System.Text,System.IO
}
process {
	if ($pscmdlet.ShouldProcess("Производим операцию чтения файла '$Path'."))
	{
		if (Test-Path $path)
		{
			[ReadLong]::ReadEndTokens($Path,$ReadCount,[System.Text.Encoding]::GetEncoding($Encoding),$Separator)
		}
		else
		{
			Write-Error "Файл $Path не найден."
		}
	}
	}
}


Read Full Post »