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

Archive for Декабрь 2010

Как включить или выключить с помощью скрипта ICS.Для этого нам потребуется два метода :
INetSharingConfiguration::EnableSharing и INetSharingConfiguration::DisableSharing.

<#

.SYNOPSIS

Конфигурирование Internet Connection Sharing.

.EXAMPLE

ICS -List
ICS -External 1 -Internal 2
ICS -External 1 -Disable

#>

param (
		#Индекс внешнего интерфейса
		[int]$External,
		#Индекс внутреннего интерфейса
		[int]$Internal,
		#Отображать ли список интерфейсов
		[switch]$List,
		#Отключить ICS
		[switch]$Disable
	  )

#Включить или отключить ICS на заданном интерфейсе
Function Set-ConnectionSharing($netint,$type)
{
	switch($netint)
	{
		#Отключить ICS
		{$_.SharingEnabled -eq $true -and $Disable} {$_.DisableSharing();break}
		{$_.SharingEnabled -eq $true} {"Internet Connection Sharing is enabled";break}
		#Включить ICS
		{$_.SharingEnabled -eq $false} {$_.EnableSharing($type);break}
		default {"Interface not found" }
	}
}
#SHARINGCONNECTIONTYPE - для внешнего интерфейса
New-Variable -Name public -Value 0 -Option Constant
#SHARINGCONNECTIONTYPE - для внутреннего интерфейса
New-Variable -Name private -Value 1 -Option Constant
#Счетчик
New-Variable -Name index -Value 1
#Создаем ComObject типа HNetCfg.HNetShare.1
$hnet = New-Object -ComObject HNetCfg.HNetShare.1
#Отображает список доступных интерфейсов
if ($List)
{
$netint = @()
	foreach ($i in $hnet.EnumEveryConnection)
	{
		$netconprop = $hnet.NetConnectionProps($i)
		$inetconf = $hnet.INetSharingConfigurationForINetConnection($i)
		$netint += New-Object PsObject -Property @{
				Index = $index
				Guid = $netconprop.Guid
				Name = $netconprop.Name
				DeviceName = $netconprop.DeviceName
				Status = $netconprop.Status
				MediaType = $netconprop.MediaType
				Characteristics = $netconprop.Characteristics
				SharingEnabled = $inetconf.SharingEnabled
				SharingConnectionType = $inetconf.SharingConnectionType
				InternetFirewallEnabled = $inetconf.InternetFirewallEnabled
				}
		$index++
	}
	$netint
}
else
{
	#Получаем список всех доступных интерфейсов и присваиваем переменной
	 $netint = $hnet.EnumEveryConnection | foreach {$hnet.INetSharingConfigurationForINetConnection($_)}
	 if ($External -and $Internal)
	 {
		 Set-ConnectionSharing $netint[$External-1] $public
		 Set-ConnectionSharing $netint[$Internal-1] $private
     }
	 elseif ($External)
	 {
	 	Set-ConnectionSharing $netint[$External-1] $public
	 }
	 elseif ($Internal)
	 {
	 	Set-ConnectionSharing $netint[$Internal-1] $private
	 }
	 else {"Parameters not set"}
}

Примеры:

PS # ICS.ps1 -List
----------------------------------------------------------------------------------------------------
Index           : 1

Guid            : {CE20A3EF-1150-4A8E-897B-21311FBDA8E8}
Name            : Local Network
DeviceName      : Atheros AR8121/AR8113/AR8114 PCI-E Ethernet Controller
Status          : 2
MediaType       : 3
Characteristics : 4105

SharingEnabled          : False
SharingConnectionType   : 0
InternetFirewallEnabled : True

----------------------------------------------------------------------------------------------------
----------------------------------------------------------------------------------------------------
Index           : 2
Guid            : {AEC05EA4-0C3B-4DA7-B90D-1D72CEF65A5A}
Name            : Internet
DeviceName      : WAN Miniport (PPTP)
Status          : 2
MediaType       : 5
Characteristics : 78

SharingEnabled          : False
SharingConnectionType   : 0
InternetFirewallEnabled : True

----------------------------------------------------------------------------------------------------
PS # ICS.ps1 -External 2
----------------------------------------------------------------------------------------------------
Index           : 2
...........................................
SharingEnabled          : True
...........................................
----------------------------------------------------------------------------------------------------
PS # ICS.ps1 -External 2 -Disable
----------------------------------------------------------------------------------------------------
Index           : 2
...........................................
SharingEnabled          : False
...........................................
----------------------------------------------------------------------------------------------------
PS # ICS.ps1 -External 2 -Internal 1

Read Full Post »

Для безопасного извлечения нам потребуется 3 функции:
1) CM_Locate_DevNodeA — для получения корневого узла дерева устройств.
2) CM_Get_Parent — для получения идентификатора устройства.
3) CM_Request_Device_Eject — ключевая функция нашего скрипта,позволяет безопасно извлечь устройство.

Для поиска занятых файлов,был использован код — Process Explorer(Большое Спасибо за него m0nax) ,оригинальная идея кода была взята с сайта.

<#

.SYNOPSIS

Безопасное извлечение USB Flash.

.EXAMPLE

Eject -List
Eject -Letter X:

#>

param (
	   #Буква раздела диска
	   [string]$Letter,
	   #Отобразить список USB дисков
	   [Switch]$List
	   )

#Основной код на C#,взят с pinvoke.
$code = @"
using System;
using System.Text;
using System.ComponentModel;
using System.Runtime.InteropServices;

namespace Usb
{
	public class Api
	{
	  public enum PNP_VETO_TYPE
     {
             Ok,

              TypeUnknown,
              LegacyDevice,
              PendingClose,
              WindowsApp,
              WindowsService,
              OutstandingOpen,
              Device,
              Driver,
              IllegalDeviceRequest,
              InsufficientPower,
              NonDisableable,
              LegacyDriver,
     }
		[DllImport("setupapi.dll", CharSet = CharSet.Auto)]
		static extern int CM_Request_Device_Eject(IntPtr devinst, out PNP_VETO_TYPE pVetoType, System.Text.StringBuilder pszVetoName, int ulNameLength, int ulFlags);
		[DllImport("setupapi.dll", SetLastError=true)]
		public static extern int CM_Locate_DevNodeA(ref int pdnDevInst, string pDeviceID, int ulFlags);
		[DllImport("setupapi.dll")]
		public static extern int CM_Get_Parent(out UInt32 pdnDevInst,UInt32 dnDevInst,int ulFlags);

		public static string Eject(int devinst)
        {
			StringBuilder sb = new StringBuilder(255);
			PNP_VETO_TYPE veto;
			IntPtr dev = new IntPtr(devinst);
            int hr = CM_Request_Device_Eject(dev, out veto, sb, sb.Capacity, 0);
			if (hr != 0)
            throw new Win32Exception(hr);
            return veto.ToString();
		}
	}
}
"@

$code1 = @"
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Runtime.CompilerServices;
using System.Runtime.ConstrainedExecution;
using System.Runtime.InteropServices;
using System.Security.Permissions;
using System.Text;
using Microsoft.Win32.SafeHandles;

namespace Detector
{
public class DetectOpenFilesEx
{
private static Dictionary<byte, string> typeHandles = new Dictionary<byte, string>();
private static Dictionary<string, string> _fileNamePrefixes = new Dictionary<string, string>();

public DetectOpenFilesEx()
{
RefreshFileNamePrefixes();
}

public FileInfo[] GetOpenedFiles(Process targetProcess)
{
Process currentProcess = Process.GetCurrentProcess();

var files = new List<FileInfo>();
var handles = GetAllHandles();

foreach (var handleEntry in handles)
{

if (handleEntry.ProcessId < 0)
throw new Exception("Process Id < 0");

if (handleEntry.ProcessId != targetProcess.Id)
continue;

string type;
if (typeHandles.ContainsKey(handleEntry.ObjectTypeNumber))
type = typeHandles[handleEntry.ObjectTypeNumber];
else
{
type = GetHandleType(handleEntry.Handle, currentProcess, targetProcess);
typeHandles.Add(handleEntry.ObjectTypeNumber, type);
}

if (String.Equals("File", type, StringComparison.InvariantCultureIgnoreCase))
{
string devicePath = GetFileNameFromHandle(handleEntry.Handle, currentProcess, targetProcess);

if (!string.IsNullOrEmpty(devicePath))
{
string goodName = ConvertDevicePathToDosPath(devicePath, false);
files.Add(new FileInfo(goodName));
}
}
}
currentProcess.Close();

return files.ToArray();
}

public SystemHandleEntry[] GetAllHandles()
{
IntPtr ptr = IntPtr.Zero;
int length = 65536;
SystemHandleInformation handles = new SystemHandleInformation();
NtStatus ret;
do
{
try
{
RuntimeHelpers.PrepareConstrainedRegions();
try
{ }
finally
{
ptr = Marshal.AllocHGlobal(length);
}

int returnLength;
ret = NativeMethods.NtQuerySystemInformation(
SystemInformationClass.SystemHandleInformation, ptr, length, out returnLength);

if (ret == NtStatus.InfoLengthMismatch)
{
length = ((returnLength + 0xffff) & ~0xffff);
}
else if (ret == NtStatus.Success)
{
{
Type typeHandleEntry = typeof(SystemHandleEntry);

int handleCount = Marshal.ReadIntPtr(ptr).ToInt32();
int sizeStruct = Marshal.SizeOf(typeof(SystemHandleEntry));

handles.NumberOfHandles = handleCount;
handles.handles = new SystemHandleEntry[handleCount];

Int64 pointer = ptr.ToInt32() + IntPtr.Size;

for (int i = 0; i < handleCount; i++)
{
handles.handles[i] = (SystemHandleEntry)Marshal.PtrToStructure(
new IntPtr(pointer + sizeStruct * i),
typeHandleEntry);
}
}
}
}
finally
{
Marshal.FreeHGlobal(ptr);
}
} while (ret == NtStatus.InfoLengthMismatch);

return handles.handles;
}

private static void RefreshFileNamePrefixes()
{
const int MAX_PATH = 254;
// Just create a new dictionary to avoid having to lock the existing one.
var newPrefixes = new Dictionary<string, string>();
for (char c = 'A'; c <= 'Z'; c++)
{
var lpTargetPath = new StringBuilder(MAX_PATH);

if (NativeMethods.QueryDosDevice(c + ":", lpTargetPath, MAX_PATH) > 2)
{
newPrefixes.Add(lpTargetPath.ToString(), c + ":");
}
}

_fileNamePrefixes = newPrefixes;
}

public string GetFileNameFromHandle(IntPtr fileHandle, Process currProc, Process targetProc)
{
SafeObjectHandle safeFileHandle = null;

RuntimeHelpers.PrepareConstrainedRegions();
try
{
bool duplOk = NativeMethods.DuplicateHandle(targetProc.Handle,
fileHandle, currProc.Handle, out safeFileHandle,
0, false, DuplicateHandleOptions.DUPLICATE_SAME_ACCESS);

if (!duplOk || safeFileHandle == null)
return null;

var nameInfo = NtQueryObject<ObjectNameInformation>(safeFileHandle.DangerousGetHandle(),
ObjectInformationClass.ObjectNameInformation);

return nameInfo.Name;
}
//catch (Exception ex)
//{
//return string.Empty;
//}
finally
{
if (safeFileHandle != null)
safeFileHandle.Close();
}
}


public string GetHandleType(IntPtr handle, Process currProc, Process targetProc)
{
SafeObjectHandle objectHandle = null;
try
{
bool duplOk = NativeMethods.DuplicateHandle(targetProc.Handle,
handle, currProc.Handle, out objectHandle, 0,
false, DuplicateHandleOptions.DUPLICATE_SAME_ACCESS);
if (duplOk)
{
var typeInfo = NtQueryObject<ObjectTypeInformation>(
objectHandle.DangerousGetHandle(),
ObjectInformationClass.ObjectTypeInformation);

return typeInfo.TypeName;
}
}
finally
{
if (objectHandle != null)
objectHandle.Close();
}

return "UNKNOWN";
}


private static T NtQueryObject<T>(IntPtr objectHandle, ObjectInformationClass typeInfo)
{
int leght = 512;
IntPtr handleInfoPtr = IntPtr.Zero;

RuntimeHelpers.PrepareConstrainedRegions();
try
{
RuntimeHelpers.PrepareConstrainedRegions();
try
{ }
finally
{
handleInfoPtr = Marshal.AllocHGlobal(leght);
}

NtStatus ret = NativeMethods.NtQueryObject(objectHandle, typeInfo, handleInfoPtr,
leght, out leght);

if (ret == NtStatus.BufferOverflow || ret == NtStatus.InfoLengthMismatch)
{
RuntimeHelpers.PrepareConstrainedRegions();
try
{ }
finally
{
handleInfoPtr = Marshal.ReAllocHGlobal(handleInfoPtr, new IntPtr(leght));
}

ret = NativeMethods.NtQueryObject(objectHandle, typeInfo, handleInfoPtr,
leght, out leght);
}

if (ret < NtStatus.Error)
{
return (T)Marshal.PtrToStructure(handleInfoPtr, typeof(T));
}
}
finally
{
Marshal.FreeHGlobal(handleInfoPtr);
}

return default(T);
}


private static string ConvertDevicePathToDosPath(string fileName, bool canonicalize)
{
bool alreadyCanonicalized = false;

// If the path starts with "\SystemRoot", we can replace it with C:\ (or whatever it is).
if (fileName.StartsWith("\\systemroot", StringComparison.OrdinalIgnoreCase))
{
fileName = Path.GetFullPath(string.Format("{0}\\..{1}", Environment.SystemDirectory, fileName.Substring(11)));
alreadyCanonicalized = true;
}
// If the path starts with "\??\", we can remove it and we will have the path.
else if (fileName.StartsWith("\\??\\"))
{
fileName = fileName.Substring(4);
}

// If the path still starts with a backslash, we probably need to 
// resolve any native object name to a DOS drive letter.)
if (fileName.StartsWith("\\"))
{
var prefixes = _fileNamePrefixes;

foreach (var pair in prefixes)
{
if (fileName.StartsWith(pair.Key + "\\"))
{
fileName = pair.Value + "\\" + fileName.Substring(pair.Key.Length + 1);
break;
}

if (fileName == pair.Key)
{
fileName = pair.Value;
break;
}
}
}

if (canonicalize && !alreadyCanonicalized)
fileName = Path.GetFullPath(fileName);

return fileName;
}





[SecurityPermission(SecurityAction.LinkDemand, UnmanagedCode = true)]
private sealed class SafeObjectHandle : SafeHandleZeroOrMinusOneIsInvalid
{
// ReSharper disable UnusedMember.Local
private SafeObjectHandle()
// ReSharper restore UnusedMember.Local
: base(true)
{ }

internal SafeObjectHandle(IntPtr preexistingHandle, bool ownsHandle)
: base(ownsHandle)
{
SetHandle(preexistingHandle);
}

protected override bool ReleaseHandle()
{
return NativeMethods.CloseHandle(handle);
}
}

#region enums

private enum SystemInformationClass
{
SystemBasicInformation = 0,
SystemPerformanceInformation = 2,
SystemTimeOfDayInformation = 3,
SystemProcessInformation = 5,
SystemProcessorPerformanceInformation = 8,
SystemHandleInformation = 16,
SystemInterruptInformation = 23,
SystemExceptionInformation = 33,
SystemRegistryQuotaInformation = 37,
SystemLookasideInformation = 45
}

private enum DuplicateHandleOptions
{
DUPLICATE_CLOSE_SOURCE = 0x1,
DUPLICATE_SAME_ACCESS = 0x2
}

private enum ObjectInformationClass
{
ObjectBasicInformation = 0,
ObjectNameInformation = 1,
ObjectTypeInformation = 2,
ObjectTypesInformation = 3,
ObjectHandleFlagInformation = 4,
ObjectSessionInformation = 5
}

private enum NtStatus : uint
{
// Success
Success = 0x00000000,

// Warning
Warning = 0x80000000,
GuardPageViolation = 0x80000001,
DatatypeMisalignment = 0x80000002,
Breakpoint = 0x80000003,
SingleStep = 0x80000004,
BufferOverflow = 0x80000005,
NoMoreFiles = 0x80000006,
HandlesClosed = 0x8000000a,
PartialCopy = 0x8000000d,
DeviceBusy = 0x80000011,
InvalidEaName = 0x80000013,
EaListInconsistent = 0x80000014,
NoMoreEntries = 0x8000001a,
LongJump = 0x80000026,
DllMightBeInsecure = 0x8000002b,

// Error
Error = 0xc0000000,
Unsuccessful = 0xc0000001,
NotImplemented = 0xc0000002,
InvalidInfoClass = 0xc0000003,
InfoLengthMismatch = 0xc0000004,
}

#endregion

#region structs

[StructLayout(LayoutKind.Sequential)]
public struct SystemHandleEntry
{
public int ProcessId;
public byte ObjectTypeNumber;
public byte Flags;
private short handleValue;
public IntPtr ObjectPointer;
public int GrantedAccess;

public IntPtr Handle
{
get { return new IntPtr(handleValue); }
}
}

[StructLayout(LayoutKind.Sequential)]
private struct SystemHandleInformation
{
public int NumberOfHandles;
public SystemHandleEntry[] handles;
}

[StructLayout(LayoutKind.Sequential)]
private struct ObjectNameInformation
{
private UnicodeString name;
public string Name
{ get { return name.Text; } }
}

[StructLayout(LayoutKind.Sequential)]
private struct UnicodeString
{
public short Length;
public short MaximumLength;
[MarshalAs(UnmanagedType.LPWStr)]
public string Text;
}

[StructLayout(LayoutKind.Sequential)]
private struct ObjectTypeInformation
{
private UnicodeString name;
public string TypeName
{ get { return name.Text; } }

public int TotalNumberOfObjects;
public int TotalNumberOfHandles;
public int TotalPagedPoolUsage;
public int TotalNonPagedPoolUsage;
public int TotalNamePoolUsage;
public int TotalHandleTableUsage;
public int HighWaterNumberOfObjects;
public int HighWaterNumberOfHandles;
public int HighWaterPagedPoolUsage;
public int HighWaterNonPagedPoolUsage;
public int HighWaterNamePoolUsage;
public int HighWaterHandleTableUsage;
public int InvalidAttributes;
public int GenericRead;
public int GenericWrite;
public int GenericExecute;
public int GenericAll;
public int ValidAccess;
public byte SecurityRequired;
public byte MaintainHandleCount;
public ushort MaintainTypeList;
public uint PoolType;
public int PagedPoolUsage;
public int NonPagedPoolUsage;
}


#endregion

#region nativeMethods

private static class NativeMethods
{
[ReliabilityContract(Consistency.WillNotCorruptState, Cer.Success)]
[DllImport("kernel32.dll", SetLastError = true)]
[return: MarshalAs(UnmanagedType.Bool)]
internal static extern bool CloseHandle(
[In] IntPtr hObject);

[DllImport("ntdll.dll")]
internal static extern NtStatus NtQuerySystemInformation(
[In] SystemInformationClass SystemInformationClass,
[In] IntPtr SystemInformation,
[In] int SystemInformationLength,
[Out] out int ReturnLength);

[DllImport("ntdll.dll")]
internal static extern NtStatus NtQueryObject(
[In] IntPtr Handle,
[In] ObjectInformationClass ObjectInformationClass,
[In] IntPtr ObjectInformation,
[In] int ObjectInformationLength,
[Out] out int ReturnLength);

[DllImport("kernel32.dll", SetLastError = true)]
[return: MarshalAs(UnmanagedType.Bool)]
internal static extern bool DuplicateHandle(
[In] IntPtr hSourceProcessHandle,
[In] IntPtr hSourceHandle,
[In] IntPtr hTargetProcessHandle,
[Out] out SafeObjectHandle lpTargetHandle,
[In] int dwDesiredAccess,
[In, MarshalAs(UnmanagedType.Bool)] bool bInheritHandle,
[In] DuplicateHandleOptions dwOptions);

[DllImport("kernel32.dll", SetLastError = true)]
internal static extern int QueryDosDevice(
[In] string lpDeviceName,
[Out] StringBuilder lpTargetPath,
[In] int ucchMax);
}

#endregion
}
}

"@

#Возвращает список USB Flash подключенных к ПК
Function Get-UsbList
{
	Get-WmiObject -Class Win32_DiskDrive -Filter "InterfaceType='USB'"| foreach {
	$PNPDeviceID = $_.PNPDeviceID
    $query = "ASSOCIATORS OF {Win32_DiskDrive.DeviceID='" `
     + $_.DeviceID + "'} WHERE ResultClass=Win32_DiskPartition" 

    Get-WmiObject -Query $query | foreach { 

        $query2 = "ASSOCIATORS OF {Win32_DiskPartition.DeviceID='" `
        + $_.DeviceID + "'} WHERE ResultClass=Win32_LogicalDisk" 

        Get-WmiObject -Query $query2 | Select-Object @{n="Name";e={"$($_.Name)\"}},
		@{n="FreeSpace(Mb)";e={$_.FreeSpace/1mb}},
    	@{n="Size(Mb)";e={$_.Size/1mb}},
		@{n="FileSystem";e={$_.FileSystem}},
		@{n="VolumName";e={$_.VolumeName}},
        @{n="PNPDeviceID";e={$PNPDeviceID}}
    	}
	}
}

#Возвращает список используемых объектов
Function Get-LockedFiles
{
	$ErrorActionPreference = "SilentlyContinue"
	$openfiles = New-Object Detector.DetectOpenFilesEx
	foreach ($i in Get-WmiObject Win32_Process | Where { $_.GetOwner().User})
	{
		try {
		if ($files=$openfiles.GetOpenedFiles((Get-Process -Id $i.ProcessId)) | Where {$_ -match "^$Letter"})
		{
			$files | Select @{n="ProcessName";e={$i.name}},
			@{n="ProcessPath";e={$i.Path}},
			Name,FullName
		}
		}
		catch {}
	}
}

#Если указан параметр List,вызвается функия Get-UsbList
if ($List)
{
	Get-UsbList
	break
}

else
{
	#Выбираем указанную букву и производим отключение
	Get-UsbList | Where {$_.Name -match $Letter} | foreach {
		$devinst = New-Object Int
		$pdnDevInst = 0
		Add-Type -TypeDefinition $code
		Add-Type -TypeDefinition $code1 -Language CSharpVersion3
		#Получаем дескриптор устройства по строке идентификатора
		[Usb.Api]::CM_Locate_DevNodeA([ref]$devinst,$_.PNPDeviceID,0) | Out-Null
		#Получаем идентификатор устройства
		[Usb.Api]::CM_Get_Parent([ref]$pdnDevInst,$devinst,0) | Out-Null
		#Удачно ли завершилась операция извлечения
		try
		{
			switch ([Usb.Api]::Eject($pdnDevInst))
			{
			 "OK" {Write-Host -ForegroundColor Yellow "Success"}
			 default {Write-Host -ForegroundColor Red $_;Get-LockedFiles}
			}
		}
		catch
		{
			Get-LockedFiles
		} 
		
	}
}

Пример использования:

PS > eject -List

Name          : H:\
FreeSpace(Mb) : 3779.06640625
Size(Mb)      : 3911.96875
FileSystem    : FAT32
VolumName     :

Name          : J:\
FreeSpace(Mb) : 51.546875
Size(Mb)      : 3791.93359375
FileSystem    : NTFS
VolumName     : Windows 7 Ru

PS > eject -Letter J
Success
PS > eject -Letter H
Success
PS > eject -Letter J: | fl

ProcessName : notepad.exe
ProcessPath : C:\Windows\system32\NOTEPAD.EXE
Name        : Portable
FullName    : J:\Program\Portable

ProcessName : notepad.exe
ProcessPath : C:\Windows\system32\NOTEPAD.EXE
Name        : Portable
FullName    : J:\Program\Distr

Read Full Post »

Для публикации кода на Pastebin.com,нам потребуется три класса: WebRequest, Steam,SteamReader.
Основная сложность возникает в формировании Post запроса.Для этого используя программу httpanalyzer и с помощью нее я получил Post запрос.

paste_code=&paste_format=perl&paste_expire_date=&paste_private=&paste_subdomain=&paste_name=&paste_email=&submit=submit

Описание этих параметров можно найти на http://pastebin.com/api.php,т.е можно было бы и не использовать httpanalyzer,но на будущее хороший инструмент для разбора запросов.

## Загружает код на pastebin.com и возвращает ссылку.
#########################################################################
## Использование:
##    1) Send-PasteBin -InputObject $PSVersionTable -Author Kazun
##	  2) Send-PasteBin -InputObject (gc script.ps1) -Author Kazun
##	  3) $Code = @'
##	  	 Write-Host "`n"
##		 Write-Host ($results | Format-Table -Auto | Out-String).Trim()
##		 Write-Host "`n"
##		 @'
##		Send-PasteBin -InputObject $code -Author Kazun
##    
#########################################################################

Function Send-PasteBin
{
	[CmdletBinding()]
	param(
		[Parameter(Mandatory=$true)]
		[Object[]]$InputObject,
		[Parameter(Mandatory=$true)]
		[String]$Author,
		[String]$Email,
		[parameter(Mandatory=$false)]
		[Int][ValidateRange(0,1)]
		$Private = 0,
		[parameter(Mandatory=$false)]
	    [String] [ValidateSet("N", "10M", "1H","1D","1M")]
		$ExpireDate = "10M",
		$Language = "powershell"
	)
		#Загружаем сборку System.Web
		Add-Type -AssemblyName System.Web
		#Url в данном случае http://pastebin.com/api_public.php
		$url = "http://pastebin.com/api_public.php"
		#Запрос для кода
		$Code = "paste_code=" + [System.Web.HttpUtility]::UrlEncode(($InputObject -join "`n"))
		#Указываем язык для подсветки(PowerShell)
		$Language = "&paste_format=" + [System.Web.HttpUtility]::UrlEncode($Language) 
		$SubDomain = "&paste_subdomain="
		#Указываем автора
		$Author = "&paste_name=" + [System.Web.HttpUtility]::UrlEncode($Author)
		#Электронная почта
		$Email = "&paste_email=" + $Email
		$Submit = "&submit=submit"
		#Формируем полный запрос для метода POST
		$data = $Code + $Language + "&paste_expire_date=$ExpireDate&paste_private=$Private" + $SubDomain + $Author +$Email + $Submit
		
		#Создаем запрос на http://pastebin.com/api_public.php
		$request = [System.Net.WebRequest]::Create($url)
		#Задает длину содержимого запрошенных к передаче данных
		$request.ContentType = "application/x-www-form-urlencoded"
		#Задает длину содержимого запрошенных к передаче данных
		$request.ContentLength = $data.Length
		#Задает метод протокола для использования в данном запросе
		$request.Method = "POST"
		
		#Инициирует запрос на передачу данных в интернет-ресурс и возвращает экземпляр 
		#Stream для передачи данных в этот интернет-ресурс
		$post = New-Object System.IO.StreamWriter $request.GetRequestStream()
		#Записывает последовательность байтов в текущий поток
		$post.Write([Char[]]$data,0,[int]$data.Length)
		#Очищает все буферы данного потока
		$post.Flush()
		#Закрывает текущий поток
		$post.Close()
		#Возвращает ответ на интернет-запрос
		$reader = New-Object System.IO.StreamReader $request.GetResponse().GetResponseStream() 
		#Считывает поток от текущего положения до конца и вывод url публикации скрипта
		Write-Host $reader.ReadToEnd()
		#Закрывает текущий поток
		$reader.Close()
}

Read Full Post »

Для авторизации на форуме воспользуемся COM объектом InternetExplorer.Application.Для навигации используем метод Navigate.Для получения всех форм на странице,воспользуемся свойством Forms.

PS > $ie.Document.forms | ? {$_.name} | ft name
name
----
web
frmLogin

Как видим у нас две формы,форму frmLogin мы и будем заполнять.После заполнения полей и нажатия кнопки «Войти» ,мы переходим в заданную тему и создаем сообщение.

#Логин
$login = "login"
#Пароль
$pass = "pass"
#Тема
$theme = "http://www.guitarplayer.ru/forum/index.php?topic=175948.0"
#Страница для авторизации
$loginpage = "http://www.guitarplayer.ru/forum/index.php?action=login"
#Создаем объект типа InternetExplorer.Application
$ie = New-Object -ComObject InternetExplorer.Application
#Переходим к странице авторизации
$ie.Navigate($loginpage)
#Ждем загрузку страницы
While ($ie.Busy) { Start-Sleep -Milliseconds 400 }
#Выбираем форму авторизации
$forms = $ie.Document.forms.namedItem("frmLogin")
#Заполняем поле логин
$forms.item("user").value= $login
#Заполняем поле пароль
$forms.item("passwrd").value = $pass
#Нажимаем на кнопку - "Войти"
($forms | where {$_.value -eq "Войти"}).click()
#Переходим к теме
$ie.Navigate2($theme)
#Выбираем форму для сообщений
$mess = $ie.Document.forms.namedItem("postmodify")
#Заполняем сообщение
$mess.item("message").value = "up"
#Нажимаем отправить
$mess.item("post").click()
#Завершаем работу
$ie.Quit()

Read Full Post »

Вадим Поданс в своем блоге описал один из методов,как сделать скриншот с помощью PowerShell,заметка — Делаем скриншоты средствами PowerShell.

В его методе на скриншоте не захватывался курсор.На форуме был задан вопрос,как захватить скриншот вместе с курсором.Сохраняется в формате год.месяц.день-часы.минуты.секунды с расширением png.

$dir="C:\Screenshot"
Add-Type -AssemblyName System.Windows.Forms
$screenBounds = [System.Windows.Forms.Screen]::PrimaryScreen.Bounds
$image = New-Object System.Drawing.Bitmap($screenBounds.Width, $screenBounds.Height)
$g = [System.Drawing.Graphics]::FromImage($image)
$p = New-Object System.Drawing.Point(0, 0)
$g.CopyFromScreen($p, $p, $image.Size);
$cursorBounds = New-Object System.Drawing.Rectangle([System.Windows.Forms.Cursor]::Position, [System.Windows.Forms.Cursor]::Current.Size)
[System.Windows.Forms.Cursors]::Default.Draw($g, $cursorBounds)
$image.Save("$dir\$((get-date).tostring('yyyy.MM.dd-HH.mm.ss')).png",[System.Drawing.Imaging.ImageFormat]::Png)

Read Full Post »

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

1)Использование Com объектов.
Для этого воспользуемся методом SendKeys объекта Wscript.Shell.Клавиши,которые можно имитировать, можно посмотреть SendKeys.

#Создаем объект WScript.Shell
$wshell = New-Object -ComObject WScript.Shell 
#Нажимаем Enter
$wshell.SendKeys("{Enter}")

Подробнее по применение ,можно прочитать http://xaegr.wordpress.com/2007/03/30/send-keys/ .

2)Использование .Net.
Здесь мы можем работать с двумя классами System.Windows.Forms.SendKeys и методом Send или
SendWait.Разница,что SendWait — ожидает окончания обработки сообщений. И второй класс Microsoft.VisualBasic.Devices.Keyboard и метода SendKeys.

Используя класс System.Windows.Forms.SendKeys и статические методы Send,SendWait.

[System.Windows.Forms.SendKeys]::Send("{Enter}")
[System.Windows.Forms.SendKeys]::SendWait("{Enter}")

Используя класс Microsoft.VisualBasic.Devices.Keyboard.

#Загружаем сборку.
[System.Reflection.Assembly]::LoadWithPartialName("Microsoft.VisualBasic")
#Создаем объект класса
$Comp = new-object Microsoft.VisualBasic.Devices.Computer
$Comp.KeyBoard.SendKeys("{ENTER}",$true)

Все рассматриваемые методы посылают имитацию нажатий в активное приложение,кроме текущего.
Для активации приложение можно воспользоваться методом AppActivate ,Interaction.AppActivate.

#Загружаем сборку.
[System.Reflection.Assembly]::LoadWithPartialName("Microsoft.VisualBasic")
#Создаем объект класса
$Comp = new-object Microsoft.VisualBasic.Devices.Computer
#Получаем pid процесса cmd.exe
$id = (gps cmd).id
#Активируем приложение cmd.exe
[Microsoft.VisualBasic.Interaction]::AppActivate($id)
Start-Sleep 1
#Посылаем Enter.
$Comp.KeyBoard.SendKeys("{ENTER}",$true)
#Создаем объект WScript.Shell
$wshell = New-Object -ComObject WScript.Shell
#Получаем pid процесса cmd.exe 
$id = (gps cmd).id
#Активируем приложение
$wshell.AppActivate($id)
start-sleep 1
$wshell.SendKeys("{Enter}")
Start-Sleep 1

Read Full Post »

На форуме technet ,был задан вопрос,как загрузить hive на удаленном компьютере.Решение было несколькими способами.

1)Использование утилиты PsExec.
Как ее использовать можно прочитать в блоге Василия Гусева (MVP по PowerShell) — http://xaegr.wordpress.com/2008/12/17/remote-process-psexec/ ,а так же http://www.osp.ru/win2000/2004/06/177161/

psexec \\comp1 reg load HKLM\TestComp "C:\Documents and Settings\TestUser\NtUser.dat"

\\comp1 — удаленный компьютер
HKLM\TestComp — в какой ключ будет загружен
«C:\Documents and Settings\TestUser\NtUser.dat» — путь на удаленном компьютере

Подробнее по reg можно прочитать в стандартной справке (reg /?).

2)Использование Wmi и метода Create класса Win32_Process.

#Создаем экземпляр класса
$proc = [WMICLASS]"\\comp1\root\cimv2:Win32_Process"
#Запускаем процесс на удаленном компьютере
$proc.Create('reg.exe load HKLM\TestComp "C:\Documents and Settings\TestUser\NtUser.dat"')

\\comp1 — удаленный компьютер
HKLM\TestComp — в какой ключ будет загружен
«C:\Documents and Settings\TestUser\NtUser.dat» — путь на удаленном компьютере

3)Использование WinApi.
Для этого нам потребуются следующие функции,которые можно найти на MSDN и их подробное описание. Так же для использования их в скрипте,потребуется объявление,которое можно найти на сайте Pinoke.

LogonUser и LogonUser — Pinvoke

ImpersonateLoggedOnUser и ImpersonateLoggedOnUse — Pinvoke
RevertToSelf и RevertToSelf — Pinvoke

RegLoadKey и RegLoadKey — Pinvoke

RegConnectRegistry и RegConnectRegistry — Pinvoke

RegUnLoadKey и RegUnLoadKey — Pinvoke

#Константа для раздела HKLM,значение можно найти в SDK.
$HKLM = 0x80000002 
#Константа для раздела HKCU,значение можно найти в SDK.
$HKCU = 0x80000003
#Подробнее LogonUser ,значение можно найти в SDK.
$LOGON32_LOGON_NEW_CREDENTIALS = 9
#Подробнее LogonUser ,значение можно найти в SDK.
$LOGON32_PROVIDER_DEFAULT = 0
#Логин учетной под которым будет осуществляться подключение.
$login = "Administrator"
#Пароль учетной записи.
$password = "P@$$w0rd"
#Домен ,где содержится учетная запись,для компьютера в локальной группе указать Ip или его имя.
$domain = "contoso.com"
#Удаленный компьютер,где проводятся действия.
$computer = "test"
#Ключ куда будет произведена загрузка Hive.
$key = "Test"
#Путь hive на удаленном компьютере.
$remotepath = "C:\Documents and Settings\Administrator\Ntuser.dat"

#Объявление функция,ссылки на Pinvoke указаны выше.
$signature = @"
[DllImport("advapi32.dll")]
public static extern int LogonUser(String lpszUserName, string lpszDomain, string lpszPassword, int dwLogonType, int dwLogonProvider, ref IntPtr phToken);

[DllImport("advapi32.dll", SetLastError=true)]
public static extern int ImpersonateLoggedOnUser(IntPtr hToken);

[DllImport("advapi32.dll", SetLastError=true)]
public static extern bool RevertToSelf();

[DllImport("advapi32.dll", SetLastError=true)]
public static extern long RegLoadKey(int hKey, String lpSubKey, String lpFile);

[DllImport("advapi32.dll", SetLastError = true)]
public static extern int RegConnectRegistry(string lpmachineName, int hKey, ref int phKResult);

[DllImport("advapi32.dll", SetLastError=true)]
public static extern int RegUnLoadKey(UInt32 hKey,string lpSubKey);

"@
#Cохраняет в переменной $signature сигнатуру C# функций,которые определенны выше.
$reg = Add-Type -MemberDefinition $signature -Name "Registry" -Namespace "Win32Functions" -PassThru

$lngTokenHandle = New-Object IntPtr(0)
$phKResult = New-Object IntPtr(0)
$blnResult = $reg::RevertToSelf()

#Возвращает результат удачно ли залогинелся пользователь.
$blnResult = $reg::LogonUser($login, $domain, $password,$LOGON32_LOGON_NEW_CREDENTIALS, $LOGON32_PROVIDER_DEFAULT, [ref]$lngTokenHandle)

if ($blnResult)
{
	#Олицетворение пользователя,для удаленного подключения.
	$reg::ImpersonateLoggedOnUser($lngTokenHandle)
}
else { "Error" }

#Подключение к удаленному реестру.
$reg::RegConnectRegistry($computer,$HKLM,[ref]$phKResult)
#Загрузка Hive.
$reg::RegLoadKey($phKResult,$key,$remotepath)
#Выгрузка Hive.
$reg::RegUnLoadKey($phKResult,$key)

Ps. Так же прочтите статью Василия Гусева — 7 способов выполнить команду на удалённом компьютере

Read Full Post »

Список аренды DHCP.

Для получение списка аренды DHCP,воспользуемся скриптом Get-DhcpClients.Так же определим ,какой пользователь залогинен в данный момент.

Param(
  [Net.IPAddress]$Server="10.0.0.1",
  [Net.IPAddress]$Scope="10.0.0.0"
)

#
# Add the namespace
#

Try { [Void][Dhcp.DhcpClient] } Catch { }
If (!$?) {

Add-Type @"
  using System;
  using System.Collections;
  using System.Net;
  using System.Runtime.InteropServices;
  using Dhcp;

  namespace Dhcp
  {
    public class ConvertTo {

      public static IPAddress IP(UInt32 Value)
      {
        Byte[] IPArray = new Byte[4];

        for (int i = 3; i > -1; i--) {
          Double Remainder = Value % Math.Pow(256, i);
          IPArray[3 - i] = (Byte)((Value - Remainder) / Math.Pow(256, i));
          Value = (UInt32)Remainder;
        }

        return IPAddress.Parse(String.Format("{0}.{1}.{2}.{3}", 
          IPArray[0],
          IPArray[1],
          IPArray[2],
          IPArray[3]));
      }

      public static UInt32 UInt32(IPAddress IP)
      {
        UInt32 Value = 0;
        Byte[] Bytes = IP.GetAddressBytes();
        for (int i = 0; i < 4; i++) {
          Value = Value | (UInt32)(Bytes[i] << (8 * (3 - i)));
        }
        return Value;
      }
    }

    public class Functions {

      [DllImport("dhcpsapi.dll")]
      public static extern UInt32 DhcpEnumSubnetClients(
        [MarshalAs(UnmanagedType.LPWStr)]
        String ServerIpAddress,
        uint SubnetAddress,
        ref uint ResumeHandle,
        uint PreferredMaximum,
        out IntPtr ClientInfo,
        out uint ClientsRead,
        out uint ClientsTotal
      );

    }

    public class Structures {

      [StructLayout(LayoutKind.Sequential)]
      public struct DATE_TIME
      {
        public UInt32 dwLowDateTime;
        public UInt32 dwHighDateTime;

        public DateTime ToDateTime()
        {
          if (dwHighDateTime == 0 && dwLowDateTime == 0)
          {
            return DateTime.MinValue;
          }
          if (dwHighDateTime == int.MaxValue && dwLowDateTime == UInt32.MaxValue)
          {
            return DateTime.MaxValue;
          }
          return DateTime.FromFileTime((((long)dwHighDateTime) << 32) | dwLowDateTime);
        }
      }

      [StructLayout(LayoutKind.Sequential)]
      public struct DHCP_BINARY_DATA
      {
        public uint DataLength;
        public IntPtr Data;

        public override String ToString()
        {
          return String.Format("{0:X2}:{1:X2}:{2:X2}:{3:X2}:{4:X2}:{5:X2}",
            Marshal.ReadByte(this.Data),
            Marshal.ReadByte(this.Data, 1),
            Marshal.ReadByte(this.Data, 2),
            Marshal.ReadByte(this.Data, 3),
            Marshal.ReadByte(this.Data, 4),
            Marshal.ReadByte(this.Data, 5));
        }
      };

      [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Auto)]
      public struct DHCP_CLIENT_INFO_ARRAY
      {
        public uint NumElements;
        public IntPtr Clients;
      }

      [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Auto)]
      public struct DHCP_CLIENT_INFO
      {
        public uint ClientIpAddress;
        public uint SubnetMask;
        public DHCP_BINARY_DATA ClientHardwareAddress;
        [MarshalAs(UnmanagedType.LPWStr)]
        public string ClientName;
        [MarshalAs(UnmanagedType.LPWStr)]
        public string ClientComment;
        public DATE_TIME ClientLeaseExpires;
        public DHCP_HOST_INFO OwnerHost;
      }

      [StructLayout(LayoutKind.Sequential)]
      public struct DHCP_HOST_INFO
      {
        uint IpAddress;
        [MarshalAs(UnmanagedType.LPWStr)]
        String NetBiosName;
        [MarshalAs(UnmanagedType.LPWStr)]
        String HostName;
      }
    }

    public class DhcpClient
    {
      public String Name;
      public String MACAddress;
      public IPAddress IpAddress;
      public IPAddress SubnetMask;
      public String Description;
      public DateTime LeaseExpires;

      internal DhcpClient(Structures.DHCP_CLIENT_INFO RawReservation)
      {
        this.IpAddress = ConvertTo.IP(RawReservation.ClientIpAddress);
        this.SubnetMask = ConvertTo.IP(RawReservation.SubnetMask);
        this.MACAddress = RawReservation.ClientHardwareAddress.ToString();
        this.Name = RawReservation.ClientName;
        this.Description = RawReservation.ClientComment;
        this.LeaseExpires = RawReservation.ClientLeaseExpires.ToDateTime();
      }

      public static DhcpClient[] Get(IPAddress ServerIP, IPAddress ScopeIP) {
        ArrayList Clients = new ArrayList();
        uint resumeHandle = 0;
        IntPtr info_array_ptr;
        uint numClientsRead = 0;
        uint totalClients = 0;

        String Server = ServerIP.ToString();
        UInt32 Scope = ConvertTo.UInt32(ScopeIP);

        UInt32 ReturnCode = Functions.DhcpEnumSubnetClients(  
          Server,
          Scope,
          ref resumeHandle,
          65536,
          out info_array_ptr,
          out numClientsRead,
          out totalClients
        );

        Structures.DHCP_CLIENT_INFO_ARRAY rawClients =  
          (Structures.DHCP_CLIENT_INFO_ARRAY)Marshal.PtrToStructure(info_array_ptr, typeof(Structures.DHCP_CLIENT_INFO_ARRAY));
        IntPtr current = rawClients.Clients;

        for (int i = 0; i < (int)rawClients.NumElements; i++) {
          Structures.DHCP_CLIENT_INFO rawMachine =  
            (Structures.DHCP_CLIENT_INFO)Marshal.PtrToStructure(Marshal.ReadIntPtr(current), typeof(Structures.DHCP_CLIENT_INFO));

          Clients.Add(new DhcpClient(rawMachine));

          current = (IntPtr)((int)current + (int)Marshal.SizeOf(typeof(IntPtr)));  
        }

        return (DhcpClient[])Clients.ToArray(typeof(DhcpClient));
      }
    }
  }
"@

}

Function Get-LoggedOn
{
	process 
	{
		if (Test-Connection -ComputerName $_.Name -Count 2 -Quiet)
		{
			$Ip = $_.IpAddress
			$Mac = $_.MACAddress
			$Comp = $_.Name
			Get-WmiObject -Class Win32_ComputerSystem -ComputerName $Comp | Select @{n="IP";e={$Ip}},@{n="Mac";e={$Mac}},UserName -Unique 
		}
	}
}

[Dhcp.DhcpClient]::Get($Server, $Scope) | Get-LoggedOn

Вывод:
Output

Read Full Post »

Воспользуемся 2 ComObject, Shell.Application и Wscript.Shell. Нам надо определить какой путь для создания надо указывать.Обратимся к ShellSpecialFolderConstants и видим,что за каждой папкой закреплена определенная константа.

Перечислим все папки и их пути:

$shellcom = New-Object -ComObject Shell.Application 
$wscriptcom = New-Object -ComObject Wscript.Shell 
0..60 | Where-Object {$shellcom.namespace($_)} | ` 
Select-Object @{l="Number";e={$_}},@{l="Folder";e={$shellcom.Namespace($_).Title}},@{l="Path";e={$shellcom.Namespace($_).Self.Path}} | ` 
Format-Table -AutoSize 

Получим вывод:

Number Folder                   Path 
------ ------                   ---- 
     0 Desktop                  C:\Users\Александр\Desktop 
     1 The Internet             ::{871C5380-42A0-1069-A2EA-08002B30309D} 
     2 Programs                 C:\Users\Александр\AppData\Roaming\Microsoft\Windows\Start Menu\Programs 
     3 All Control Panel Items  ::{26EE0668-A00A-44D7-9371-BEB064C98683}0 
     4 Printers                 ::{21EC2020-3AEA-1069-A2DD-08002B30309D}::{2227A280-3AEA-1069-A2DE-08002B30309D}  

Теперь создадим ярлыки на рабочем столе.

$shellcom = New-Object -ComObject Shell.Application 
$wscriptcom = New-Object -ComObject Wscript.Shell 

foreach ($i in @(10,17,18)) 
{ 
    $shrtk = $wscriptcom.CreateShortcut($shellcom.Namespace(0).Self.Path +"\" + $shellcom.Namespace($i).Title + ".lnk") 
    $shrtk.TargetPath = $shellcom.Namespace($i).Self.Path 
    $shrtk.Save() 
}  

Read Full Post »

Определить простой операционной системы,на основе последнего события ввода пользователя.Для этого используем функцию GetLastInputInfo.Для создания форм,использовался Primal Forms.

$code = @'
using System;
using System.Diagnostics;
using System.Runtime.InteropServices;

namespace Idle
{
   public static class Timer
   {
      [DllImport("user32.dll", SetLastError=false)]
      private static extern bool GetLastInputInfo(ref LASTINPUTINFO plii);

      [StructLayout(LayoutKind.Sequential)]
      private struct LASTINPUTINFO
      {
         public uint cbSize;
         public int dwTime;
      }

      public static DateTime LastInput
      {
         get
         {
            LASTINPUTINFO lii = new LASTINPUTINFO();
            lii.cbSize = (uint)Marshal.SizeOf(typeof(LASTINPUTINFO));
            GetLastInputInfo(ref lii);
            DateTime bootTime = DateTime.Now.AddMilliseconds(-Environment.TickCount);
            DateTime lastInput = bootTime.AddMilliseconds(lii.dwTime);
            return lastInput;
         }
      }
      public static TimeSpan IdleTime
      {
         get
         {
         return DateTime.Now.Subtract(LastInput);
         }
      }
   }
}
'@

Add-Type $code
Function UpdateLabel
{
   $label3.Text = [Idle.Timer]::IdleTime
   $label4.Text = [Idle.Timer]::LastInput.ToString()
}

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

$form1 = New-Object System.Windows.Forms.Form
$label4 = New-Object System.Windows.Forms.Label
$label3 = New-Object System.Windows.Forms.Label
$label2 = New-Object System.Windows.Forms.Label
$label1 = New-Object System.Windows.Forms.Label
$timer =  New-Object System.Windows.Forms.Timer

$timer.Interval=1000
$timer.Start()
$timer.add_Tick({Updatelabel})

$form1.Text = "Idle Timer"
$form1.FormBorderStyle  = [System.Windows.Forms.FormBorderStyle]::FixedDialog
$form1.ClientSize = New-Object System.Drawing.Size(249,79)

$label4.Size = New-Object System.Drawing.Size(153,23)
$label4.Font = New-Object System.Drawing.Font("Microsoft Sans Serif",8.25,1,3,0)
$label4.Location = New-Object System.Drawing.Point(77,44)
$label4.Text = [Idle.Timer]::LastInput.ToString()

$form1.Controls.Add($label4)

$label3.Size = New-Object System.Drawing.Size(153,23)
$label3.Font = New-Object System.Drawing.Font("Microsoft Sans Serif",8.25,1,3,0)
$label3.Location = New-Object System.Drawing.Point(77,17)
$label3.DataBindings.DefaultDataSourceUpdateMode = 0
$label3.Text = [Idle.Timer]::IdleTime
$form1.Controls.Add($label3)

$label2.Size = New-Object System.Drawing.Size(81,23)
$label2.Text = "Last Input:"
$label2.Font = New-Object System.Drawing.Font("Microsoft Sans Serif",8.25,0,3,0)
$label2.Location = New-Object System.Drawing.Point(13,44)

$form1.Controls.Add($label2)

$label1.Size =  New-Object System.Drawing.Size(81,19)
$label1.Text = "Idle Time:"
$label1.Font = New-Object System.Drawing.Font("Microsoft Sans Serif",8.25,0,3,0)
$label1.Location = New-Object System.Drawing.Point(13,17)
$label1.Name = "label1"
$form1.Controls.Add($label1)

$form1.ShowDialog()

Read Full Post »

Older Posts »