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

Archive for the ‘PowerShell V3’ Category

Рассмотрим 2 метода:

  1. Используя Com объект  InternetExplorer.Application
  2. Используя командлет Invoke-WebRequest (появился с версии 3.0)

 

Учетом успешного выполнения скрипта, будет вывод сообщения – “Ваш последний визит был: время”

1.  InternetExplorer.Application

Определим, какие поля нам требуется заполнить, достаточно просто.

В поля  “Имя Пользователя” и “Пароль” подставим значения  ,и посмотрим, какие  поля требуют заполнения.

ie

PS >  $ie.Document.forms.Item(1) | Format-Table Name,Value -Auto

name                     value
----                     -----
vb_login_username        abc
cookieuser               1
vb_login_password        abc
                         Войти
s
do                       login
vb_login_md5password
vb_login_md5password_utf

 

Как видно выше для заполнения нужны поля vb_login_username и vb_login_password.


# Имя пользователя
$login = "MyUser"
# Пароль
$pass = "Password"
# Адрес страницы
$url = "http://forum.oszone.net"
# Создание Com-объекта
$ie = New-Object -ComObject InternetExplorer.Application
# Переход к заданному адресу
$ie.Navigate($url)
# Ждем загрузки страницы
while($ie.Busy) { Start-Sleep -Milliseconds 100 }

# Объект страницы
$doc = $ie.Document
# Заполняем поле - Имя пользователя
$doc.getElementsByName("vb_login_username") | % {$_.Value = $login}
# Заполняем поле - Пароль
$doc.getElementsByName("vb_login_password") | % {$_.Value  = $pass}
# Снимаем галочку - Сохранить
$doc.getElementsByName("cookieuser") | % {$_.Value  = 0}

# Находим кнопку войти - нажимаем ее
$doc.getElementsByTagName("input") | ? {$_.Value -eq "Войти"} | % {$_.Click()}
while($ie.Busy) { Start-Sleep -Milliseconds 100 }
# После авторизации, получаем данные
$doc.Body.OuterText.Split("`r`n") -match "Ваш последний визит"

 

2. Invoke-WebRequest

Определим, какие поля нам требуется заполнить у формы.

PS >  $r.Forms[1].Fields | Format-Table -Auto

Key                      Value
---                      -----
navbar_username          Имя пользователя
cb_cookieuser_navbar     1
vb_login_password
s                        7f2a40e2749a7bf18b1b371
do                       login
vb_login_md5password
vb_login_md5password_utf

 

Требуется нам заполнить все поля или достаточно определенных. В этом нам поможет Fiddler.

  • Запускаем Fiddler
  • Запускаем любой браузер ( логирование командлета Invoke-WebRequest тоже поддерживается)
  • Переходим на сайт
  • Заполняем поля , нажимаем “Войти”
  • Смотрим Post запрос

iw

 

Поле vb_login_password – пустое, но вычисляется md5 hash пароля.

$md5 = [Security.Cryptography.MD5]::Create()
$bstr = [Text.Encoding]::ASCII.GetBytes("abc")
$hash = (-join ($md5.ComputeHash($bstr) | %{ "{0:X2}" -f $_})).ToLower()
$hash
900150983cd24fb0d6963f7d28e17f72

Для ASCII символов, если пароль в Unicode, данный метод не подойдет. Какой алгоритм преобразования

пароля содержащего Unicode символы — http://forum.oszone.net/clientscript/vbulletin_md5.js?v=364

Вычислим поле vb_login_md5password для Unicode , на примере – Привет:

$str = -join([char[]]"Привет" | % {"&#"+ ([int][char]$_) +";"})
(-join ($md5.ComputeHash([Text.Encoding]::ASCII.GetBytes($str))| %{ "{0:X2}" -f $_})).ToLower()

«&#»+ [int][char]П –> 1055 + “;” = “П”

Вычислим поле vb_login_md5password_utf для Unicode , на примере – Привет:

$str = [int[]][char[]]"Привет" | % {$_ -band 255} 
(-join ($md5.ComputeHash($str) | %{ "{0:X2}" -f $_})).ToLower()

При использовании полей vb_login_md5password и vb_login_md5password_utf, поле vb_login_password – не заполняем.

Но можно не утруждать себя данными алгоритмами, а просто заполнить поля vb_login_username и vb_login_password.

$login = "MyUser"
$pass = "Password"
$url = "http://forum.oszone.net"
$r = Invoke-WebRequest $url -SessionVariable oz
$form = $r.Forms[1]
$form.Fields["vb_login_username"] = $login
$form.Fields["vb_login_password"] = $pass
$r = Invoke-WebRequest -Uri ("$url/" + $form.Action)`
    -WebSession $oz -Method POST -Body $form.Fields
$r = Invoke-WebRequest -Uri $url -WebSession $oz
$r.ParsedHtml.Body.OuterText.Split("`r`n") -match "Ваш последний визит"

 

В конечном итоге получим вывод:

output

 

Реклама

Read Full Post »

Что нам потребуется:

  • Аккаунт на gmail.com
  • Включенный Imap(Настройки – Пересылка и POP/IMAP)

image

  • Скачать библиотеку ImapX — https://imapx.codeplex.com за авторством Павла Азанова – за что ему большая благодарность

Для использования данной библиотеки сначала ее надо загрузить:

Add-Type -Path "C:\IMAPX\v4.5\InterIMAP.dll"

1) Подключение к почтовому серверу Imap

ImapX позволяет указать сервер, порт и шифрование тремя различными способами:

1. С помощью одного из параметризованных конструкторов при инициализации нового ImapClient

2. Используя свойства клиента

3. Настройка параметров подключения прямо при вызове метода Connect


Инициализация клиента:

#Без SSL, порт по умолчанию (143) для соединения
$client= New-Object ImapX.ImapClient("imap.gmail.com") 

#С поддержкой SSL, порт по умолчанию (993) для соединения
$client = New-Object ImapX.ImapClient("imap.gmail.com",$true) 
#С поддержкой SSL, порт по умолчанию (993) для соединения, 
#    отключить проверку сертификата
$client = New-Object ImapX.ImapClient("imap.gmail.com",$true,$false)  

#Без SSL, с указанием порта для соединения
$client = New-Object ImapX.ImapClient("imap.gmail.com",888) 

#С поддержкой SSL, с указанием порта для соединения
$client = New-Object ImapX.ImapClient("imap.gmail.com",888,$true) 

#С поддержкой SSL, с указанием порта для соединения, 
#    отключить проверку сертификата
$client = New-Object ImapX.ImapClient("imap.gmail.com",888,$true,$false) 

#С поддержкой TLS, с указанием порта для соединения, 
#    отключить проверку сертификата
$client = New-Object ImapX.ImapClient("imap.gmail.com",888,
    [System.Security.Authentication.SslProtocols]::Tls,$false) 

Подключение:

if($client.Connect( # опциональные параметры # )) {# подключение прошло успешно}
else {
     # подключиться не удалось
}

Какие параметры можно передать методу Connect:

bool Connect()                                                                                                                                                           
bool Connect(string host, bool useSsl, bool validateServerCertificate)                                                                                                   
bool Connect(string host, int port, bool useSsl, bool validateServerCertificate)                                                                                         
bool Connect(string host, int port, 
    System.Security.Authentication.SslProtocols sslProtocol, 
    bool validateServerCertificate) 

2) Аутентификация

ImapX – поддерживает два встроенных метода: логин — пароль и OAuth2.

# Используя связку Логин - Пароль
$client = New-Object ImapX.ImapClient("imap.gmail.com","993",$true,$true)

if($client.Connect()) {  
    if($client.Login("address@gmail.com", "password")) {
        # подключение прошло успешно    }
}
else {
    # подключиться не удалось
}
# Используя OAuth2
$client = New-Object ImapX.ImapClient("imap.gmail.com","993",$true,$true)

if($client.Connect()) {   
    $credentials = New-Object`
        ImapX.Authentication.OAuth2Credentials("login", "token")

    if($client.Login(credentials)) {
        # подключение прошло успешно     
}
}
else {
    # подключиться не удалось
}

3) Работа с папками

В Gmail папки не используются,вместо них есть ярлыки,но будем считать папка = ярлык.

Для доступа к папкам воспользуемся свойством Folders(для нашего примера $client.Folders) класса ImapX.ImapClient.

Просмотр общих папок:

ImapX обеспечивает прямой доступ ко всем общим папкам как Inbox, Drafs, Trash и другие. Учтите, что это не всегда возможно определить эти папки, так как не все сервера предоставляют необходимую информацию .

Общие папки по умолчанию:

PS >  [ImapX.Collections.CommonFolderCollection].GetProperties().Name

All

Archive

Inbox

Drafts

Important

Flagged

Junk

Sent

Для выбора определенной папки,можно воспользоваться индексом массива или методом Item:

# Просмотр папок почтового ящика
PS > $client.Folders.Name
INBOX
[Gmail]
Личные
Путешествие
Работа
Счета

# Выберем папку вся почта
PS > $client.Folders.All

Exists                : 6
Recent                : 0
Recents               : 0
Unseen                : 0
SubFolders            : {}
Messages              : {}
GMailThreads          : {}
HasChildren           : False
Name                  : Вся почта
Selectable            : True
Path                  : [Gmail]/&BBIEQQRP- &BD8EPgRHBEIEMA-
FolderPath            : [Gmail]/&BBIEQQRP- &BD8EPgRHBEIEMA-
Flags                 : {\HasNoChildren, \All}
AllowedPermanentFlags : {}
UidNext               : 1357
UidValidity           : 624695359
SubFolder             : 

# Выберем папку входящая почта
$client.Folders.Inbox
$client.Folders.Item("INBOX")
$client.Folders[0]
$client.Folders["INBOX"]
# Просмотр подпапок(свойство SubFolders)
PS > $client.Folders.Item("[Gmail]").SubFolders.Name
Важное
Вся почта
Корзина
Отправленные
Помеченные
Спам
Черновики

Создание папок:

# Создадим папку -  Новости
PS > $client.Folders.Add("Новости")

Exists                : 0
Recent                : 0
Recents               : 0
Unseen                : 0
SubFolders            : {}
Messages              : {}
GMailThreads          : {}
HasChildren           : False
Name                  : Новости
Selectable            : True
Path                  : &BB0EPgQyBD4EQQRCBDg-
FolderPath            : &BB0EPgQyBD4EQQRCBDg-
Flags                 : {}
AllowedPermanentFlags : {}
UidNext               : 1
UidValidity           : 624695382
SubFolder             : 

# Создадим подпапку BBC в разделе Новости
$client.Folders["Новости"].CreateFolder("BBC")

или

$client.Folders["Новости"].SubFolders.Add("BBC")

PS > $client.Folders["Новости"].SubFolders.Add("BBC")

Exists                : 0
Recent                : 0
Recents               : 0
Unseen                : 0
SubFolders            : {}
Messages              : {}
GMailThreads          : {}
HasChildren           : False
Name                  : BBC
Selectable            : True
Path                  : &BB0EPgQyBD4EQQRCBDg-/BBC
FolderPath            : &BB0EPgQyBD4EQQRCBDg-/BBC
Flags                 : {}
AllowedPermanentFlags : {}
UidNext               : 1
UidValidity           : 624695384
SubFolder             : 

Переименование папок:

# Для переименования достаточно изменить свойство Name

PS  >  $client.Folders[«Новости«].Name =«Кино«

 

Удаление папок:

# Удалим папку Кино
PS > $client.Folders["Кино"].Remove()
True

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

Lazy или Full

По умолчанию ImapX загрузит два уровня  дерева папок при обращении к свойству Folders. Вложенные папки, которые глубже —  по требованию. Если вы хотите получить  всю структуру папок при первом запросе,  измените поведение клиента:

$client.Behavior.FolderTreeBrowseMode = «Full»

Автоматическая проверка папок

По умолчанию ImapX проверяет папки (например, запрашивает общее количество сообщений и последние сообщения), когда структура дерева загружается. Если вам не нужно эту информацию сразу же, вы можете отключить автоматическое обследование:

$client.Behavior.ExamineFolders = $false

4) Работа с сообщениями

ImapX позволяет выбрать способ, как запрашиваются сообщения. Вы можете установить режим загрузки глобально или индивидуально для поиска или одного сообщении.

Определить глобальный тип загрузки для сообщений:

По умолчанию, глобальный режим загрузки установлен на Basic. В этом режиме запрашиваются флаги, заголовки, структуру тела, размер, внутреннюю дату и тело сообщения (за исключением встроенных изображений и вложений).

# Возможные значения свойства — MessageFetchMode

PS > [enum]::GetNames("ImapX.Enums.MessageFetchMode")
Flags
InternalDate
Size
Headers
BodyStructure
Tiny
Minimal
Body
Basic
Attachments
Full
GMailMessageId
GMailThreads
GMailLabels
GMailExtendedData
None
ClientDefault

$client.Behavior.MessageFetchMode = «Basic»

MessageFetchMode.Tiny — флаги,заголовки и структура тела письма

MessageFetchMode.Minimal — флаги,заголовки,структура тела письма,размер и внутреннюю дату

MessageFetchMode.Basic — флаги,заголовки,структура тела и тело письма,размер и внутреннюю дату

MessageFetchMode.Full — флаги,заголовки,тело письма,вложения,размер и внутреннюю дату

Доступ к  сообщениям:

По умолчанию коллекция Messages  объекта Folder будет пустым. Для загрузки сообщений, воспользуемся метод Download:

# Загрузим все сообщения из папки All
$client.Folders.All.Messages.Download()

# Загрузим первые 3 сообщения из папки All
$client.Folders.All.Messages.Download("All",-1,3)
# Загрузим 1 сообщения из папки Inbox от YouTube
$client.Folders.Inbox.Messages.Download('FROM "YouTube"',-1,1)

Если вы не хотите вызвать метод Download  для каждой папки, можно просто задать поведение клиента для автоматического заполнения коллекции Folder.Messages.

$client.Behavior.AutoPopulateFolderMessages = $true

Запрос сообщений используя  метод Folder.Search:

Также можно использовать метод Folder.Search для запроса сообщений. Все найденные сообщения будут возвращены методом Search будут  добавлены к коллекции Folder.Messages. Метод Messages.Download() вызывает метод Folder.Search, поэтому оба метода принимают одинаковые параметры.

PS > $client.Folders.Inbox.Search

OverloadDefinitions
——————-
ImapX.Message[] Search(string query, ImapX.Enums.MessageFetchMode mode, int count)
ImapX.Collections.MessageCollection Search(string path, bool makeProcess) – Является устаревшим и не испольуется

# Найти все сообщения в папке INBOX
$client.Folders.Inbox.Search()

# Найти первое сообщение в папке INBOX
$client.Folders.Inbox.Search(1)

# Найти пятое сообщение в папке INBOX
$client.Folders.Inbox.Search(5)

# Найти первые пять сообщений в папке INBOX( 0x19 - MessageFetchMode.Tiny)
$client.Folders.Inbox.Search("All",0x19,5)

Для формирования фильтра,более подробно можно прочитать в RFC 3501 пункт 6.4.4.

# Найти все сообщения в папке INBOX
$client.Folders.Inbox.Search()

# Найти первое сообщение в папке INBOX
$client.Folders.Inbox.Search(1)

# Найти пятое сообщение в папке INBOX
$client.Folders.Inbox.Search(5)

# Найти первые пять сообщений в папке INBOX( 0x19 - MessageFetchMode.Tiny)
$client.Folders.Inbox.Search("All",0x19,5)

# Найдем сообщения, где в теле письма(BODY) есть YouTube
$client.Folders.Inbox.Search('BODY "YouTube"',0x19,-1)

# Найдем все сообщения от YouTube
$client.Folders.Inbox.Search('FROM "YouTube"')

# Найдем сообщения первое сообщение от YouTube
$client.Folders.Inbox.Search('FROM "YouTube"',0x19,1)

date            = date-day "-" date-month "-" date-year
date-day        =1*2DIGIT
date-month      ="Jan"/"Feb"/"Mar"/"Apr"/"May"/"Jun"/"Jul"/"Aug"/"Sep"/"Oct"/"Nov"/"Dec"
# Найдем сообщения полученные от 1 декабря 2013 года
$client.Folders.Inbox.Search('SINCE "01-DEC-2013"')

# Найдем сообщения полученные  30 ноября 2013 года
$client.Folders.Inbox.Search('ON "30-NOV-2013"') 

# Найдем сообщения в тему у которых есть слово Windows
$client.Folders.Inbox.Search('SUBJECT "Windows"')

Скачивание вложений:

# Просмотр вложений
$m.Attachments

# Имя файла
$m.Attachments.ContentType.Name

# Прежде,чем сохранить или работать с Steam,требуется загрузить Download()
$m.Attachments.Download()

# Проверить загрузку объекта
$m.Attachments.Downloaded

# Сохраним вложение
$m.Attachments.Save("C:\files",$m.Attachments.ContentType.Name)

Копирование сообщений:

# Скопируем сообщение в папку Trash
$m=$client.Folders.Trash.Search('FROM "test@xxx.ru"')
$m[0].CopyTo($client.Folders.Trash,$true)

Удаление сообщений:

# Найсти все сообщений от YouTube и удалить
$client.Folders.Inbox.Search('FROM "YouTube"') | 
    ForEach-Object {$_.Remove()}

Работа с флагами:

# Флаги сообщения
$m=$client.Folders.Trash.Search('FROM "test@xxx.ru"')
$m.Flags

# Добавим флаг \SEEN
$m=$client.Folders.Trash.Search('FROM "test@xxx.ru"')
$m.Flags.Add("\SEEN")

# Удалим флаг \SEEN
$m=$client.Folders.Trash.Search('FROM "test@xxx.ru"')
$m.Flags.Remove("\SEEN")

Экспорт сообщений:

# Экспорт сообщения в файл
$m=$client.Folders.Inbox.Messages[0]
$m.Save("C:\message.eml")
$m.SaveTo("C:\","message.eml")

5) Отключение от почтового сервера Imap

# Disconnect
$client.Disconnect()
Remove-Variable -Name client

PS. Если Вам понравилась библиотека ImapX, Вы можете выразить благодарность Павлу Азанову:

Donate

Read Full Post »

По мотивам — Powershell и Google Drive API (Загрузить файл на гугл диск)

1) Скачиваем и устанавливаем Google Data APIs (GData)

2) Создаем аккаунт Google, если отсутствует  — https://accounts.google.com 

3) Переходим на сайт  https://cloud.google.com/console

4) Создаем новое или выбираем существующий проект

project

5) Переходим в меню APIs & auth  -> APIs

6) Включаем нужные API (Drive API и Drive SDK) в значение ON

api

7) Переходим в меню APIs & auth  -> Registered apps и нажать Register app

8) Указать название приложения(для нашего примера Test) и выбрать тип Native

regapp

9) Выбираем наше приложение и выбираем пункт Update(требуется указать почтовый адрес и название нашего приложения)

native

content

Воспользуемся примером кода «Uploading a new document or file with both metadata and content«.

#Загружаем требуемые библиотеки(путь может быть изменен,Program Files)
Add-Type -Path "C:\Program Files (x86)\Google\Google Data API SDK\Redist\Google.GData.Documents.dll"
Add-Type -Path "C:\Program Files (x86)\Google\Google Data API SDK\Redist\Google.GData.Client.dll"

#Учетные данные Google Account
$glogin = 'Login'
$gpass = 'password'

#Файл для загрузки
$FileToUpload = "C:\PDF\wp__understanding-wmi-malware.pdf"
# Имя файла без расширения
$fname = [System.IO.Path]::GetFileNameWithoutExtension($FileToUpload)

#Указываем API, отделяя их запятой,список - https://support.google.com/a/answer/162106?hl=ru
$scopes = "https://docs.google.com/feeds/ https://docs.googleusercontent.com/"

#Подтавляем данные из пункта №9
$param = New-Object Google.GData.Client.OAuth2Parameters -Property @{
	ClientId = "ID"
	ClientSecret = "Secret"
	RedirectUri = "urn:ietf:wg:oauth:2.0:oob"
	Scope = $scopes
}

#Получаем ссылку для авторизации OAuth
$url = [Google.GData.Client.OAuthUtil]::CreateOAuth2AuthorizationUrl($param)

#После перехода по ссылке получаем код
$ie = New-Object -ComObject InternetExplorer.Application
$ie.Navigate($url)
While ($ie.busy -eq $true)
      {Start-Sleep -Milliseconds 500}
While ($ie.Document.Title -match "не подключены")
      {Start-Sleep -Milliseconds 500}
If ($ie.Document.Title -match "Вход"){
    $login=$ie.document.getElementByID("Email")
    $login.Value=$glogin
    $pass=$ie.document.getElementByID("Passwd")
    $pass.Value=$gpass
    $ie.document.getElementByID("signIn") | Foreach {$_.click()}
    While ($ie.busy -eq $true)
            {Start-Sleep -Milliseconds 500}
}

If ($ie.Document.Title -match "Запрос на разрешение")
{
    $ie.Document.Forms.Item(0) | where {$_.innerText -eq "Принять"} | Foreach {$_.click()}
    While ($ie.busy -eq $true)
            {Start-Sleep -Milliseconds 500}
    If($ie.Document.Body.outerHTML -match 'value="(.+)"><script')
            {$global:param.AccessCode = $matches[1]}
 }
 $ie.Quit()

#Получаем токен авторизации и создаем аутентификатор
[Google.GData.Client.OAuthUtil]::GetAccessToken($param)
$authenticator = New-Object Google.GData.Client.OAuth2Authenticator("Test",$param)
$rf = new-object Google.GData.Client.GOAuth2RequestFactory("apps", "Test", $param)

$service = New-Object Google.GData.Documents.DocumentsService("Test")
$service.RequestFactory = $rf

#Формируем документ на отправку
$dentry=New-Object Google.GData.Documents.DocumentEntry
$dentry.Title.Text="$fname"
$dentry.MediaSource=New-Object Google.GData.Client.MediaFileSource($FileToUpload,"application/pdf")
$createUploadUrl=New-Object System.Uri("https://docs.google.com/feeds/upload/create-session/default/private/full")
$link=New-Object Google.GData.Client.AtomLink($createUploadUrl)
$link.Rel = [Google.GData.Client.ResumableUpload.ResumableUploader]::CreateMediaRelation
$dentry.Links.Add($link)

$dentry.Service=$service

#Загрузка файла
$uploader=New-Object Google.GData.Client.ResumableUpload.ResumableUploader
Register-ObjectEvent -InputObject $uploader -EventName AsyncOperationProgress -Action {
	Write-Progress -activity Upload -status 'Progress->' -percentcomplete $EventArgs.ProgressPercentage} | Out-Null
Register-ObjectEvent -InputObject $uploader -EventName AsyncOperationCompleted -Action {
	Get-EventSubscriber | Unregister-Event -Force
	Write-Host -ForegroundColor Yellow "Completed!!!"
} | Out-Null
$uploader.InsertAsync($authenticator, $dentry, (new-object object))

Read Full Post »

1) Как установить  PowerShell V4?

.NET Framework 4.5 (В состав Windows 8.1 и Windows Server 2012,Windows Server 2012 R2 входит .NET Framework 4.5. Поэтому установка этого программного обеспечения в указанных операционных системах не требуется.)  должен быть установлен перед установкой Windows Management Framework 4.0 (WMF).

PowerShell является частью пакета Windows Management Framework 4.0 (WMF) и может быть скачан по следующим ссылкам:

Windows Management Framework 4.0 (WMF)  нельзя установить на  Windows 8, поэтому следует обновиться до Windows 8.1.

WMF 3.0  и Windows PowerShell 2.0 engine не требуются для установки WMF 4.0. Однако, Windows PowerShell 2.0 engine может быть установлен отдельно, используя Server Manager или Control Panel,  для тестирования сценариев,которые используют функциональность Windows PowerShell 2.0 (Powershell.exe -Version, Start-Job -PSVersion, and Register-PSSessionConfiguration –PSVersion).  При установленном WMF 3.0  и Windows PowerShell 2.0 engine , можно выбрать для запуска Windows PowerShell 2.0 или Windows PowerShell 3.0. После установки WMF 4.0,можно работать с  Windows PowerShell 2.0 или Windows PowerShell 4.0. Windows PowerShell 4.0 обратно совместим с Windows PowerShell 3.0, за исключением указанных в разделе Breaking Changes документа WINDOWS MANAGEMENT Framework 4.0 Release Notes.

Windows PowerShell V4 несовместим:

  • System Center 2012 Configuration Manager (not including SP1)
  • System Center Virtual Machine Manager 2008 R2 (including SP1)
  • Microsoft Exchange Server 2013, Microsoft Exchange Server 2010, and Microsoft Exchange Server 2007
  • Microsoft SharePoint 2013 and Microsoft SharePoint 2010
  • Windows Small Business Server 2011 Standard

Полезные ссылки по установке и запуску Windows PowerShell:

2) Какие компоненты были обновлены?

  • Windows PowerShell
  • Windows PowerShell Integrated Scripting Environment (ISE)
  • Windows PowerShell Web Services (Management OData IIS Extension)
  • Windows Remote Management (WinRM)
  • Windows Management Instrumentation (WMI)

3) Какие новые компоненты были добавлены?

  • Windows PowerShell Desired State Configuration (DSC)

4) Версионность PowerShell

Изменения:

  • Значение переменной $PSVersionTable.PSVersion  обновлено до  4.0

PS >  $PSVersionTable.PSVersion

Major  Minor  Build  Revision
——  ——  ——  ———
4      0      -1     -1

  • Изменен баннер copyright

Windows PowerShell
Copyright (C) 2013 Microsoft Corporation. All rights reserved.

  • Версия  Windows PowerShell 4.0 заменяет версию 3.0. Запросы для загрузки версии 3.0 автоматически загружают версию 4.0. Например,  Powershell.exe –Version 3.0 автоматически загружает версию 4.0
  • Session configurations  автоматически загружает версию 4.0, вместо 3.0
  • Командлеты использующие при запуске определенную версию Windows PowerShell, автоматически используют версию 4.0, если указана версия 3.0.  Такие  командлеты,как  Start-Job, Set-PSSessionConfiguration, и Register-PSSessionConfiguration с параметром -PSVersion <Version>
  • Значение ключа реестра HKLM:\SOFTWARE\Microsoft\PowerShell\3\PowerShellEngine\PowerShellVersion изменно с  3.0 на 4.0

PS  >  Get-ItemProperty -Path HKLM:\SOFTWARE\Microsoft\PowerShell\3\PowerShellEngine -Name PowerShellVersion

PowerShellVersion : 4.0

  • Значение ключа реестра HKLM:\SOFTWARE\Microsoft\PowerShell\3\PowerShellEngine\PSCompatibleVersion изменно с  1.0, 2.0, 3.0 на 1.0, 2.0, 3.0, 4.0

PS >  Get-ItemProperty -Path HKLM:\SOFTWARE\Microsoft\PowerShell\3\PowerShellEngine -Name PSCompatibleVersion

PSCompatibleVersion : 1.0, 2.0, 3.0, 4.0

Не измененные значения:

  • Переменная $pshome ссылается на  %windir%\system32\WindowsPowerShell\v1.0
  • Расширение скриптов Windows PowerShell имеет значение  .ps1
  • Значение ключей реестра Windows PowerShell расположены по адресу  HKLM:\SOFTWARE\Microsoft\PowerShell\1 и HKLM:\SOFTWARE\Microsoft\PowerShell\3

5)  Execution Policy по умолчанию в Windows Server 2012 R2?

Значение Execution Policy по умолчанию в Windows Server 2012 R2 установлено в RemoteSigned. Execution Policy для Windows 8.1 по умолчанию Restricted.

6) Новый параметр –IncludeUserName типа switch у командлета Get-Process

Данный параметр позволяет получить список пользователей от которых запущен процесс. Данный параметр требует запускать с повышенными привилегиями.

PS >  Get-Process -IncludeUserName
Get-Process : The ‘IncludeUserName’ parameter requires elevated user rights. Try running the command again in a session that has been opened with elevated user rights (that is, Run as Administrator).

Пример:

PS >  Get-Process -IncludeUserName | Where UserName -match System | Format-Table Name,UserName

Name          UserName
—-          ———
armsvc    NT AUTHORITY\SYSTEM
csrss         NT AUTHORITY\SYSTEM
csrss         NT AUTHORITY\SYSTEM

Для более ранних версий Windows PowerShell:

7) Новый командлет(функция) Get-FileHash

PS  >  (Get-Command Get-FileHash).CommandType
Function

Посмотреть код функции: — ${function:Get-FileHash}

Используя командлет Get-Member или исходный код функции,можно увидеть,что функция имеет тип retVal.psobject.TypeNames.Insert(0, «Microsoft.Powershell.Utility.FileHash»).

Также можно посмотреть,какое форматирование использует данная функция.

PS >  (Get-FormatData Microsoft.Powershell.Utility.FileHash).FormatViewDefinition.Control

Name                                                        Control
—-                                                        ——-
Microsoft.Powershell.Utility.FileHash                       TableControl

Далее можно посмотреть столбцы по умолчанию:

PS >  (Get-FormatData Microsoft.Powershell.Utility.FileHash).FormatViewDefinition.Control.Rows.Columns

Alignment DisplayEntry
——— ————
Undefined Algorithm
Undefined Hash
Undefined Path

Параметр Algorithm поддерживает следующие параметры:

PS >  (Get-Command Get-FileHash).Parameters[«Algorithm»].Attributes.ValidValues
SHA1
SHA256
SHA384
SHA512
MACTripleDES
MD5
RIPEMD160

Примеры:

PS >  Get-FileHash $pshome\powershell.exe | Format-List

Algorithm : SHA256
Hash      : E9FA973EB5AD446E0BE31C7B8AE02D48281319E7F492E1DDAADDDFBDD5B480C7
Path      : C:\Windows\System32\WindowsPowerShell\v1.0\powershell.exe

PS >  Get-FileHash $pshome\powershell.exe -Algorithm Sha1| Format-List

Algorithm : SHA1
Hash      : 10A3671C0FBC2BCE14FC94891E87E2F4BA07E0DF
Path      : C:\Windows\System32\WindowsPowerShell\v1.0\powershell.exe

Для более ранних версий Windows PowerShell:

  • Модуль PSCX и командлет Get-Hash
  • Скрипт на .Net под авторством Boe Prox — Get Hashes of Files
  • Скрипт на .Net под авторством Lee Holmes — Get-FileHash.ps1

8) Переименовали параметр Workgroup у командлета Remove-Computer

В PowerShell 3.0  командлету Remove-Computer добавили параметр Workgroup(позволяет указать имя рабочей группы,после отсоединения компьютера из домена). В PowerShell 4.0 переименовали данный параметр с Workgroup на WorkgroupName  ,теперь оба командлета Add-Computer и Remove-Computer используют единый параметр –WorkgroupName.

9) Новый параметр FullyQualifiedName у командлета Get-Module

В PowerShell 4.0 командлету Get-Module добавили новый параметр типа ModuleSpecification[].

Формат параметра  —  @{ModuleName = «modulename»; ModuleVersion = «version_number»;GUID=»guid»}.  ModuleName и ModuleVersion(желательно придерживаться формата n.n.n.n) – обязательные.

Пример:

PS >  Get-Module -FullyQualifiedName @{ModuleName=»AppLocker»;ModuleVersion=»1.0.0.0″} –ListAvailable

PS >  Get-Module -Name AppLocker -ListAvailable | Format-Table Name,Version,GUID -AutoSize

Name      Version Guid
—-      ——- —-
AppLocker 1.1.0.0 27807c40-84db-4998-ae01-11319de093ea
AppLocker 1.0.0.0 9dafd409-67de-4108-8ee9-73cd61f5b7bf

PS >  Get-Module -FullyQualifiedName @{ModuleName=»AppLocker»;ModuleVersion=»1.0.0.0″;GUID=»27807c40-84db-4998-ae01-11319de093ea»} –ListAvailable

10) Новый параметр PassThru у командлетов Enable-JobTrigger и Disable-JobTrigger

Параметр Passthru отображает все объекты, созданные или измененные с помощью командлета.

Пример:

PS >  Get-ScheduledJob | Get-JobTrigger

Id         Frequency       Time                   DaysOfWeek              Enabled
—         ———       —-                   ———-              ——-
1          Weekly          11.11.2013 23:00:00    {Monday, Wednesday, … True

PS >  Get-ScheduledJob | Get-JobTrigger | Disable-JobTrigger -PassThru

Id         Frequency       Time                   DaysOfWeek              Enabled
—         ———       —-                   ———-              ——-
1          Weekly          11.11.2013 23:00:00    {Monday, Wednesday, … False

11) Новый параметр RepeatIndefinitely у командлетов New-JobTrigger и Set-JobTrigger

Параметр RepeatIndefinitely позволяет избавиться от использования конструкции вида -RepetitionDuration ([TimeSpan]::MaxValue), которая служит для неоднократного запуска запланированного задания на неопределенный срок.

Пример:

PS >  New-JobTrigger -Once -At «1/11/2013» -RepetitionInterval (New-TimeSpan -Hour 2) -RepetitionDuration ([TimeSpan]::MaxValue)

Теперь команду можно записать:

PS >  New-JobTrigger -Once -At «1/11/2013» -RepetitionInterval (New-TimeSpan -Hour 2) -RepeatIndefinitely

Команда создает job trigger ,который запускает раз в 2 часа на неопределенный срок. Старт задачи 1/11/2013 – 0:00:00.

12) Новый параметр RunNow у командлетов Register-ScheduledJob и Set-ScheduledJob

Параметр RunNow позволяет не указывать параметр trigger для job для немедленного  выполнения задачи без указания даты и времени.

Пример:

PS >  Register-ScheduledJob -Name Test-FileName -FilePath C:\Scripts\TestFile.ps1 –RunNow

13) Изменения в командлете Save-Help?

Командлет Save-Help теперь позволяет сохранить справку для модулей(modules), которые установленные на удаленных компьютерах. В PowerShell 3.0 командлет Save-Help позволял работать только с локальным компьютером. Хотя есть возможность экспортировать модуль с удаленного компьютера,используя Windows PowerShell remoting и получить ссылку на объект PSModuleInfo, свойство HelpInfoUri не сохраняется. В PowerShell 4.0 свойство HelpInfoUri сохраняется, что позволяет Save-Help работать с удаленными модулями. Также возможно сохранить объект PSModuleInfo на диск или внешний накопитель используя командлет Export-CliXml  на компьютере без доступа к интернету, импортировать объект на компьютере с интернетом и запустить Save-Help на десериализованном объектее PSModuleInfo. Сохраненный файлы помощи можно перенести на исходный компьютер и обновить справку с помощью командлета Update-Help.

Пример:

Example 1: Run Save-Help to save the help for the DhcpServer module from an Internet-connected client computer, without installing the DhcpServer module or DHCP Server role on the local computer.

# Option 1: Run Invoke-Command to get the remote module and call Save-Help

$m = Invoke-Command -ComputerName RemoteServer -ScriptBlock { Get‑Module ‑Name DhcpServer -ListAvailable }

Save-Help -Module $m -DestinationPath C:\SavedHelp

# Option 2: Use a PSSession to get the remote module and call Save-Help

$s = New-PSSession -ComputerName RemoteServer

$m = Get-Module -PSSession $s -Name DhcpServer -ListAvailable

Save-Help -Module $m -DestinationPath C:\SavedHelp

# Option 3: Use a CimSession to get the remote module and call Save-Help

$c = New-CimSession -ComputerName RemoteServer

$m = Get-Module -CimSession $c -Name DhcpServer -ListAvailable

Save-Help -Module $m -DestinationPath C:\SavedHelp

Example 2: Install help for the DhcpServer module on a computer without any network access.

# Run Export-CliXml to serialize the PSModuleInfo object to disk or removable media

$m = Get-Module -Name DhcpServer –ListAvailable

Export-CliXml –Path E:\UsbFlashDrive\DhcpModule.xml –InputObject $m

# Transport the removable media to a computer with Internet access and import with Import-CliXml

$deserialized_m = Import-CliXml E:\UsbFlashDrive\DhcpModule.xml

Save-Help -Module $deserialized_m -DestinationPath E:\UsbFlashDrive\SavedHelp

# Transport the removable media back to the computer without network access and install the help

Update-Help –Module DhcpServer –SourcePath E:\UsbFlashDrive\SavedHelp

Read Full Post »

NetSh vs NETTCPIP модуль на простой задаче

1) Посмотреть сетевые интерфейсы в системе
netsh int ipv4 show int

Idx     Met         MTU          State                Name
—  ———-  ———-  ————  —————————
1          50  4294967295  connected     Loopback Pseudo-Interface 1
12          10        1500  connected     Ethernet

2) Сконфигурируем статический адрес
netsh int ipv4 set address «Ethernet» static 192.168.100.100 255.255.255.0 192.168.100.1

PS. В отличии от командлета New-NetIPAddress утилита netsh не проверяет из какой подсети шлюз
netsh int ipv4 set address «Ethernet» static 192.168.100.100 255.255.255.0 10.10.10.1

IPv4 Address. . . . . . . . . . . : 192.168.100.100
Subnet Mask . . . . . . . . . . . : 255.255.255.0
Default Gateway . . . . . . . . . : 10.10.10.1

3) Изменим шлюз по умолчанию
netsh int ipv4 set address «Ethernet» static 192.168.100.100 255.255.255.0 192.168.100.2

IPv4 Address. . . . . . . . . . . : 192.168.100.100
Subnet Mask . . . . . . . . . . . : 255.255.255.0
Default Gateway . . . . . . . . . : 192.168.100.2

4) Удалим шлюз по умолчанию
netsh int ipv4 set address «Ethernet» static 192.168.100.100 255.255.255.0

IPv4 Address. . . . . . . . . . . : 192.168.100.100
Subnet Mask . . . . . . . . . . . : 255.255.255.0
Default Gateway . . . . . . . . . :

5) Изменим со статического адреса на dhcp
netsh int ipv4 set address «Ethernet» dhcp

IPv4 Address. . . . . . . . . . . : 192.168.0.26
Subnet Mask . . . . . . . . . . . : 255.255.255.0
Default Gateway . . . . . . . . . : 192.168.0.1

С утилитой netsh проблем не возникает.

Теперь попробуем произвести подобные манипуляции с модулем NETTCPIP.

1) Посмотреть сетевые интерфейсы в системе
Get-NetAdapter

Name                       : Ethernet
InterfaceIndex             : 12
InterfaceOperationalStatus : Up
AdminStatus                : Up
LinkSpeed(Gbps)            : 1
MediaConnectionState       : Connected
ConnectorPresent           : True

2) Убедимся,что адрес получен через DHCP
Get-NetIPConfiguration

InterfaceAlias       : Ethernet
InterfaceIndex       : 12
IPv4Address          : 192.168.0.26
IPv4DefaultGateway   : 192.168.0.1
DNSServer            : 192.168.0.96

3) Сконфигурируем статический адрес на интерфейсе с номером 12
New-NetIPAddress –InterfaceIndex 12 –IPAddress 192.168.100.100 -PrefixLength 24 -DefaultGateway 192.168.100.1

InterfaceAlias       : Ethernet
InterfaceIndex       : 12
IPv4Address          : 192.168.100.100
IPv4DefaultGateway   : 192.168.100.1
DNSServer            : 192.168.0.96

PS. Если мы укажем шлюз не из той подсети,то получим ошибку:
New-NetIPAddress –InterfaceIndex 12 –IPAddress 192.168.100.100 -PrefixLength 24 -DefaultGateway 10.10.10.1

New-NetIPAddress : DefaultGateway 10.10.10.1 is not on the same network segment (subnet) that is defined by the IP addr
ess 192.168.100.100 and PrefixLength 24.
At line:1 char:1
+ New-NetIPAddress -InterfaceIndex 12 -IPAddress 192.168.100.100 -PrefixLength 24  …
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo          : InvalidArgument: (MSFT_NetIPAddress:ROOT/StandardCimv2/MSFT_NetIPAddress) [New-NetIPAddr
ess], CimException
+ FullyQualifiedErrorId : Windows System Error 87,New-NetIPAddress

4) Изменим шлюза по умолчанию

1) Remove-NetIPAddress&New-NetIPAddress

С этим уже сложнее,т.к. командлет Set-NetIPAddress не содержит параметр для измения шлюза по умолчанию.

a) Удалим ранее установленные параметры
    Remove-NetIPAddress -InterfaceIndex 12 -DefaultGateway 192.168.100.1 -Confirm:$false
b) Установим коректные значения
New-NetIPAddress –InterfaceIndex 12 –IPAddress 192.168.100.100 -PrefixLength 24 -DefaultGateway 192.168.100.2

PS. Но и тут не без сюрприза,если установить шлюз из другой подсети(например 10.10.10.1),
то шлюз по умолчанию удалить с помощью Remove-NetIPAddress не получится,пока не назначим адрес из подсети шлюза.
При использовании Remove-NetRoute проблем не возникает.

IPv4DefaultGateway   : 10.10.10.1

2) New-NetRoute&Remove-NetRoute
a) Добавим новый шлюз
New-NetRoute -InterfaceIndex 12 -NextHop 192.168.100.2 -DestinationPrefix 0.0.0.0/0

InterfaceAlias       : Ethernet
InterfaceIndex       : 12
IPv4Address          : 192.168.100.100
IPv4DefaultGateway   : {192.168.100.2, 192.168.100.1}
DNSServer            : 192.168.0.96

b) Удалим старый шлюз
  Remove-NetRoute -InterfaceIndex 12 -NextHop 192.168.100.1 -Confirm:$false

InterfaceAlias       : Ethernet
InterfaceIndex       : 12
IPv4Address          : 192.168.100.100
IPv4DefaultGateway   : 192.168.100.2
DNSServer            : 192.168.0.96

5) Удалим шлюз по умолчанию
1) Используя Remove-NetRoute
a) Remove-NetRoute -InterfaceIndex 12 -NextHop 192.168.100.1 -Confirm:$false
InterfaceAlias       : Ethernet
InterfaceIndex       : 12
IPv4Address          : 192.168.100.100
IPv4DefaultGateway   :
DNSServer            : 192.168.0.96
b) Remove-NetRoute -InterfaceIndex 12 -DestinationPrefix 0.0.0.0/0 -Confirm:$false
Позволяет удалить,когда больше 2-ух шлюзов по умолчанию

2) Используя Remove-NetIPAddress
a) Удалим ранее установленные параметры
Remove-NetIPAddress -InterfaceIndex 12 -DefaultGateway 192.168.100.1 -Confirm:$false
b) Установим коректные значения
New-NetIPAddress –InterfaceIndex 12 –IPAddress 192.168.100.100 -PrefixLength 24

6) Изменим со статического адреса на dhcp
Set-NetIPInterface -InterfaceIndex 12 -Dhcp Enabled

PS. В этом случае остается шлюз по умолчанию,что нам совершенно не нужно.

New-NetIPAddress -InterfaceIndex 12 -IPAddress 192.168.100.100 -PrefixLength 24 -DefaultGateway 192.168.100.2

InterfaceAlias       : Ethernet
InterfaceIndex       : 12
IPv4Address          : 192.168.100.100
IPv4DefaultGateway   : {192.168.100.2, 192.168.100.1}
DNSServer            : 192.168.0.96

Теперь у нас два шлюза.
a) Удалим ранее установленные параметры(остается шлюз 192.168.100.2)
   Remove-NetIPAddress -InterfaceIndex 12 -DefaultGateway 192.168.100.1 -Confirm:$false
b) Установим коректные значения
    New-NetIPAddress –InterfaceIndex 12 –IPAddress 192.168.100.100 -PrefixLength 24
с) Удалим теперь второй шлюз
    Remove-NetIPAddress -InterfaceIndex 12 -DefaultGateway 192.168.100.2 -Confirm:$false
d) Установим получать через DHCP
Set-NetIPInterface -InterfaceIndex 12 -Dhcp Enabled

или

Set-NetIPInterface -InterfaceIndex 12 -Dhcp Enabled
    Remove-NetRoute -InterfaceIndex 12 -NextHop 192.168.100.1 -Confirm:$false

Read Full Post »

Вопрос был задан на форуме OsZone.Net в теме «PowerShell — Закрытие всех окон приложений кроме активного« . Был предложен вариант с ярлыком, но возникла проблема, при нажатии hotkey  — фокус приложения переключался на другое приложение.

Что нам потребуется:

Основная проблема – это работа с hotkey. Идея работы позаимствована у Hans Passant’a — How to prevent my C# winforms application from stealing focus when I set the visible properly to true?

Схема скрипта:

  • Функция RegisterHotKey —  определяет комбинацию «горячая» клавиша для текущего потока

RegisterHotKey(this.Handle, MYKEYID, MOD_CONTROL + MOD_SHIFT, Keys.U);

  • this.Handle  — Идентификатор окна нашей формы,которое принимает сообщение WM_HOTKEY
  • MYKEYID — Определяет идентификатор комбинации
  • MOD_CONTROL + MOD_SHIFT — Определяет клавиши, которые должны быть нажаты в комбинации с клавишей, заданной параметром vk, чтобы генерировать сообщение WM_HOTKEY. Параметр modifiers может быть комбинацией следующих значений:
    • MOD_ALT — Любая клавиша ALT должна удерживаться нажатой.
    • MOD_CONTROL — Любая клавиша CTRL должна удерживаться нажатой.
    • MOD_SHIFT — Любая клавиша SHIFT должна удерживаться нажатой.
  • Keys.U — Определяет код виртуальной клавиши комбинации «горячая» клавиша.

В данном примере комбинация будет CTRL+Shift + U

  • Функция  UnregisterHotKey — освобождает комбинацию «горячая» клавиша, предварительно зарегистрированную вызывающим потоком

UnregisterHotKey(this.Handle, MYKEYID);

  • this.Handle  — Идентификатор окна нашей формы,которое принимает сообщение WM_HOTKEY
  • MYKEYID — Определяет идентификатор комбинации

Вызывается при закрытии формы

  • Для обработки сообщений операционной системы в нашей форме, потребуется переопределить метод WndProc.
  • if (m.Msg == WM_HOTKEY && m.WParam.ToInt32() == MYKEYID) { – Производим проверку на получение сочетания CTRL+Shift +
  • Вызов скрипта PowerShell —  How to run PowerShell scripts from C#
  • Import-Module -Name Wasp\r\nSelect-Window | Where-Object { -not $_.IsActive} | Remove-Window
    • Import-Module -Name Wasp – Импортирует модуль WASP (не обязательно для PowerShell V3, но с учетом того,что переменная $PSModuleAutoloadingPreference не None)
    • Select-Window – Получаем список окон
    • Where-Object { -not $_.IsActive} – Отфильтровываем все кроме активного
    • Remove-Window – Закрываем окна
  • Function OnLoad –  Определяем свойства для запуска формы в скрытом режиме
  • Function OnClick – При нажатии на кнопку меню Exit – закрываем форму
  • Создаем значок в трее и определяем меню Exit
  • Запуск формы
$ActiveWindow = @'
using System;
using System.Windows.Forms;
using System.Runtime.InteropServices;
using System.Management.Automation;
using System.Management.Automation.Runspaces;

namespace WindowsApplication1 {
public partial class Form1 : Form {
private const int MYKEYID = 0;
public Form1() {
RegisterHotKey(this.Handle, MYKEYID, MOD_CONTROL + MOD_SHIFT, Keys.U);
this.FormClosing += Form1_FormClosing;
}
private void Form1_FormClosing(object sender, FormClosingEventArgs e) {
UnregisterHotKey(this.Handle, MYKEYID);
}

protected override void SetVisibleCore(bool value)
{
base.SetVisibleCore(false);
}

protected override void WndProc(ref Message m) {
if (m.Msg == WM_HOTKEY && m.WParam.ToInt32() == MYKEYID) {
// create Powershell runspace
Runspace runspace = RunspaceFactory.CreateRunspace();

// open it
runspace.Open();

// create a pipeline and feed it the script text
string scriptText = "Import-Module -Name Wasp\r\nSelect-Window | Where-Object { -not $_.IsActive} | Remove-Window";
Pipeline pipeline = runspace.CreatePipeline();
pipeline.Commands.AddScript(scriptText);

// execute the script
pipeline.Invoke();

// close the runspace
runspace.Close();
}
base.WndProc(ref m);
}

// P/Invoke declarations
private const int WM_HOTKEY = 0x312;
private const int MOD_ALT = 1;
private const int MOD_CONTROL = 2;
private const int MOD_SHIFT = 4;
[DllImport("user32.dll")]
private static extern int RegisterHotKey(IntPtr hWnd, int id, int modifier, Keys vk);
[DllImport("user32.dll")]
private static extern bool UnregisterHotKey(IntPtr hWnd, int id);
}
}
'@

Function OnLoad {
$form.Visible = $false
$form.ShowInTaskbar = $false
}

Function OnClick {
$trayIcon.Visible = $False
$form.close()
}

Add-Type -TypeDefinition $ActiveWindow -ReferencedAssemblies System.Windows.Forms
Add-Type -AssemblyName System.Drawing

$trayIcon = New-Object System.Windows.Forms.NotifyIcon
$trayMenu = New-Object System.Windows.Forms.ContextMenu
$menuExit = New-Object System.Windows.Forms.MenuItem
$form = New-Object WindowsApplication1.Form1

$trayIcon.Icon = [System.Drawing.SystemIcons]::Information
$trayIcon.ContextMenu = $trayMenu

$menuExit.Text = "Exit"
$menuExit.Add_Click({OnClick})

$trayMenu.MenuItems.AddRange(@($menuExit))

$form.Add_Load({OnLoad})

$trayIcon.Visible = $true
[Windows.Forms.Application]::Run($form)

Запуск скрипта:

Powershell –WindowStyle Hidden –File «C:\Script\Close-InactiveWindow.ps1»

Выход:

Read Full Post »

1) С помощью служебной программы Diskpart с интерфейсом командной строки

Назначение: Windows Xp, Windows Vista, Windows 7, Windows 8, Windows Server 2003, Windows Server 2008, Windows Server 2008 R2, Windows Server 2012

Программа Diskpart позволяет выполнять расширенный набор действий, поддерживаемых оснасткой "Управление дисками". Оснастка "Управление дисками" защищает данные на диске путем блокирования действий, которые могут привести к их повреждению. Будьте внимательны, используя программу Diskpart, поскольку она предоставляет явный контроль над разделами и томами!

Для получение статуса программного массива – воспользуемся командой "list volume":

#Вывод для русской локализации

PS >  "list volume" | diskpart 

DISKPART> 
  
  Том ###     Имя      Метка     ФС     Тип              Размер    Состояние  Сведения    
  ----------  ---  -----------  -----  ----------------  -------  ----------  --------
  Том 0         F   My RAID Set  NTFS   RAID-5            4096 МБ  Исправен
  Том 1         G   FATSTRIPE    FAT32  Чередующийся том  6144 МБ  Неисправен
  Том 2         H   My Mirror    NTFS   Зеркальный том    2048 МБ  Исправен
  Том 3         I   My Span      NTFS   Составной том        9 ГБ  Исправен
  Том 4         D                CDFS   CD-ROM               0 Б
  Том 5         C                NTFS   Раздел            2047 МБ  Исправен    Системный
  Том 6         Е                NTFS   Раздел            2063 МБ  Исправен    Загрузочный
  Том 7         J   My Primary   NTFS   Раздел            4095 МБ  Исправен
  Том 8         K   My Logical   NTFS   Раздел            2047 МБ  Исправен
  Том 9         L   My Next Log  NTFS   Раздел            2534 МБ  Исправен

#Вывод для английской локализации

DISKPART>  
  
  Volume ###  Ltr  Label        Fs     Type              Size     Status      Info    
  ----------  ---  -----------  -----  ----------------  -------  ----------  --------
  Volume 0     F   My RAID Set  NTFS   RAID-5            4096 MB  Healthy
  Volume 1     G   FATSTRIPE    FAT32  Stripe            6144 MB  Failed
  Volume 2     H   My Mirror    NTFS   Mirror            2048 MB  Healthy
  Volume 3     I   My Span      NTFS   Spanned              9 GB  Healthy
  Volume 4     D                CDFS   CD-ROM               0 B
  Volume 5     C                NTFS   Partition         2047 MB  Healthy     System
  Volume 6     E                NTFS   Partition         2063 MB  Healthy     Boot
  Volume 7     J   My Primary   NTFS   Partition         4095 MB  Healthy
  Volume 8     K   My Logical   NTFS   Partition         2047 MB  Healthy
  Volume 9     L   My Next Log  NTFS   Partition         2534 MB  Healthy

 

Более подробно — How Basic Disks and Volumes Work

 

2) Используя VDS (Virtual Disk Services) API

Назначение:  Windows Vista, Windows 7, Windows 8, Windows Server 2003, Windows Server 2008, Windows Server 2008 R2, Windows Server 2012

Microsoft Storage VDS Library — позволяет получить  статус программного массива. Но данная библиотека является недокументированной и неподдерживаемой, хотя и поставляется вместе с ОС. Так что используем на свой страх и риск.

  • Для работы с библиотекой требуются права Администратора
  • При использовании Windows 7,Windows Vista – требуется установить Remote Server Administration Tools (RSAT) и компонент из набора Share and Storage Management Tools

 

 

Перечисления:

  • VDS_VOLUME_STATUS – статус тома
    VDS_VS_UNKNOWN

    The status of the volume is unknown. This value does not apply to dynamic volumes.

    VDS_VS_ONLINE

    The volume is available.

    VDS_VS_NO_MEDIA

    The volume is removable media, such as a CD-ROM.

    VDS_VS_FAILED

    The volume is unavailable.

    VDS_VS_OFFLINE

    The volume is offline.

  • VDS_VOLUME_TYPE – тип тома
    VDS_VT_UNKNOWN

    The volume type is unknown.

    VDS_VT_SIMPLE

    The volume type is simple—it is composed of extents from exactly one disk.

    VDS_VT_SPAN

    The volume type is spanned—it is composed of extents from more than one disk.

    VDS_VT_STRIPE

    The volume type is striped, which is equivalent to RAID 0.

    VDS_VT_MIRROR

    The volume type is mirrored, which is equivalent to RAID 1.

    VDS_VT_PARITY

    The volume type is striped with parity, which accounts for RAID levels 3, 4, 5, and 6.

  • VDS_HEALTH – здоровье тома
# Загрузка сборки Microsoft Storage VDS Library  
[Reflection.Assembly]::LoadWithPartialName("Microsoft.Storage.Vds") | Out-Null 
$VdsServiceLoader = New-Object Microsoft.Storage.Vds.ServiceLoader 
$VdsService = $VdsServiceLoader.LoadService($null) 
$VdsService.WaitForServiceReady() 

# Получим коллекцию томов присутствующих в системе
$volumes = $VdsService.Providers  | foreach {$_.packs} | foreach {$_.volumes}

# Выведем свойства Буква диска,тип,статус,"здоровье" 
$volumes | Select DriveLetter,Type,Status,Health

Пример вывода:

Windows PowerShell

Copyright (C) 2012 Microsoft Corporation. All rights reserved.

PS >.\GetVolumeStatus.ps1

DriveLetter   Type Status  Health

————   —- ——  ——

          G  Mirror   Online  Healthy

          E  Span     Online  Healthy

          F  Stripe   Online  Healthy

          D  Simple   Online  Healthy 
             Simple   Online  Healthy

          C  Simple   Online  Healthy



 

3) Используя командлет Get-Volume из модуля Storage

Назначение:  Windows 8,  Windows Server 2012

В Windows 8,Windows Server 2012 появился новый WMI класс MSFT_Volume. Комадлет Get-Volume является обвязкой для этого класса. Есть один существенный минус – нет возможности определить тип тома.

Требования:

  • Minimum supported client — Windows 8 [desktop apps only]
  • Minimum supported server — Windows Server 2012 [desktop apps only]
  • Namespace — \\.\Root\Microsoft\Windows\Storage
  • MOF — Storagewmi.mof

Пример вывода:

Windows PowerShell

Copyright (C) 2012 Microsoft Corporation. All rights reserved.

PS > Get-Volume | Format-Table -AutoSize DriveLetter,HealthStatus

DriveLetter HealthStatus

———— ————

            Healthy

          C Healthy

          E Healthy

          F Healthy

            Healthy

          D Healthy



 

PS. ИМХО самое простое и эффективное средство – является DiskPart

Read Full Post »

Older Posts »