Thursday, July 31, 2014

Powershell: Converting VBScript to Powershell

Below is a script directly from the Windows 2000 Scripting Guide:

Retrieving System Information
Computer Assets, Listing 8.1

Description
Retrieves information similar to that returned by the System Information utility.


Script Code


Set objWMIService = GetObject("winmgmts:" _
    & "{impersonationLevel=impersonate}!\\" & strComputer & "\root\cimv2")
Set colSettings = objWMIService.ExecQuery _
    ("SELECT * FROM Win32_OperatingSystem")
For Each objOperatingSystem in colSettings
    Wscript.Echo "OS Name: " & objOperatingSystem.Name
    Wscript.Echo "Version: " & objOperatingSystem.Version
    Wscript.Echo "Service Pack: " & _
        objOperatingSystem.ServicePackMajorVersion _
            & "." & objOperatingSystem.ServicePackMinorVersion
    Wscript.Echo "OS Manufacturer: " & objOperatingSystem.Manufacturer
    Wscript.Echo "Windows Directory: " & _
        objOperatingSystem.WindowsDirectory
    Wscript.Echo "Locale: " & objOperatingSystem.Locale
    Wscript.Echo "Available Physical Memory: " & _
        objOperatingSystem.FreePhysicalMemory
    Wscript.Echo "Total Virtual Memory: " & _
        objOperatingSystem.TotalVirtualMemorySize
    Wscript.Echo "Available Virtual Memory: " & _
        objOperatingSystem.FreeVirtualMemory
    Wscript.Echo "OS Name: " & objOperatingSystem.SizeStoredInPagingFiles
Next
Set colSettings = objWMIService.ExecQuery _
    ("SELECT * FROM Win32_ComputerSystem")
For Each objComputer in colSettings
    Wscript.Echo "System Name: " & objComputer.Name
    Wscript.Echo "System Manufacturer: " & objComputer.Manufacturer
    Wscript.Echo "System Model: " & objComputer.Model
    Wscript.Echo "Time Zone: " & objComputer.CurrentTimeZone
    Wscript.Echo "Total Physical Memory: " & _
        objComputer.TotalPhysicalMemory
Next
Set colSettings = objWMIService.ExecQuery _
    ("SELECT * FROM Win32_Processor")
For Each objProcessor in colSettings
    Wscript.Echo "System Type: " & objProcessor.Architecture
    Wscript.Echo "Processor: " & objProcessor.Description
Next
Set colSettings = objWMIService.ExecQuery _
    ("SELECT * FROM Win32_BIOS")
For Each objBIOS in colSettings
    Wscript.Echo "BIOS Version: " & objBIOS.Version
Next

How can this be converted to Powershell?

$strComputer = "."
$iret = [reflection.assembly]::LoadWithPartialName("'Microsoft.VisualBasic")
$objWMIService= [Microsoft.VisualBasic.Interaction]::GetObject("winmgmts:impersonationLevel=impersonate}!\\" + $strComputer + "\root\cimv2")
$colSettings = $objWMIService.ExecQuery("SELECT * FROM Win32_OperatingSystem")
foreach($objOperatingSystem in $colSettings)
{
    write-host "OS Name: "$objOperatingSystem.Name
    write-host "Version: "$objOperatingSystem.Version
    $strsp =  $objOperatingSystem.ServicePackMajorVersion
    $strsp = $strsp + "."
    $strsp = $strsp + $objOperatingSystem.ServicePackMinorVersion
    write-host "Service Pack: "$strsp
    write-host "OS Manufacturer: "$objOperatingSystem.Manufacturer
    write-host "Windows Directory: "$objOperatingSystem.WindowsDirectory
    write-host "Locale: "$objOperatingSystem.Locale
    write-host "Available Physical Memory: "$objOperatingSystem.FreePhysicalMemory
    write-host "Total Virtual Memory: "$objOperatingSystem.TotalVirtualMemorySize
    write-host "Available Virtual Memory: "$objOperatingSystem.FreeVirtualMemory
    write-host "OS Name: "$objOperatingSystem.SizeStoredInPagingFiles
}
$colSettings = $objWMIService.ExecQuery("SELECT * FROM Win32_ComputerSystem")
foreach($objComputer in $colSettings)
{
    write-host "System Name: "$objComputer.Name
    write-host "System Manufacturer: "$objComputer.Manufacturer
    write-host "System Model: "$objComputer.Model
    write-host "Time Zone: "$objComputer.CurrentTimeZone
    write-host "Total Physical Memory: "$objComputer.TotalPhysicalMemory
}
$colSettings = $objWMIService.ExecQuery("SELECT * FROM Win32_Processor")
foreach($objProcessor in $colSettings)
{
     write-host "System Type: "$objProcessor.Architecture
     write-host "Processor: "$objProcessor.Description
}
$colSettings = $objWMIService.ExecQuery("SELECT * FROM Win32_BIOS")
foreach($objBIOS in $colSettings)
{
     write-host "BIOS Version: "$objBIOS.Version
}

And there you have it.










Powershell: Does a value exist in the registry

param
(
        [Parameter(Mandatory=$True)]
        [string]$subkeyname,
        [Parameter(Mandatory=$True)]
        [string]$ValueName,
)

$regkey = [Microsoft.Win32.Registry]::ClassesRoot
$value = $regkey.OpenSubKey($subkeyname).GetValue($ValueName)
if(!($value))
{
    write-host "Value does not exist."
}
else
{
    write-host "Value exists."
}

Powershell: Get a List of Registry Key Values

This code shows you how to acquire a list of value names after specifying a key path:

param
(
    [Parameter(Mandatory=$True)]
    [string]$Subkey,
    [Parameter(Mandatory=$True)]
    [string]$Filter
)

    $regkey = [Microsoft.Win32.Registry]::ClassesRoot
    if($Subkey)
    {
        $Names = $regkey.GetSubKeyNames()
        $NameList = New-Object 'System.Collections.Generic.List[string]'
       
        foreach($n in $Names)
        {
            $pos = $n.IndexOf($Filter)
           
            if ($pos -ne -1)
            {
                write-host $n  
                $NameList.Add($n)
        }   
        }     
    }
    else
    {
        $Names = $regkey.OpenSubKey($Subkey).GetSubKeyNames()
        $NameList = New-Object 'System.Collections.Generic.List[string]'
        foreach($n in $Names)
        {
            $pos = $n.IndexOf($Filter)
            if ($pos -gt 0)
            {
                write-output $n
                $NameList.Add($n)
        }   
        }
    }
   

Powershell: Discover if a registry key exists

This code is only one example and is targeted at the HKEY_CLASSES_ROOT:

param
(
   [Parameter(Mandatory=$True)]
   [string]$Subkey
)
function Test-Registry-key
{
    param
    (
        [Parameter(Mandatory=$True)]
        [Microsoft.Win32.RegistryKey]$Regkey,
        [Parameter(Mandatory=$True)]
        [string]$key
    )
    $rkey = $regkey.OpenSubKey($key)
    if(!($rkey))
    {
        return "Key does not exist."
    }
    else
    {
        return "Key exists."
    }

}
$regkey = [Microsoft.Win32.Registry]::ClassesRoot
$ret = Test-Registry-Key $regkey $Subkey
write-host $ret

Powershell: Working With The Registry Part 2

In  part one, we covered some of the primary functions of the Microsoft Win32 API.

Now, it is time to share some more knowledge:

When you use the RegistryKey.OpenBaseKey, you can choose three options:

  1. [Microsoft.Win32.RegistryKey]::OpenBaseKey([Microsoft.Win32.RegistryHive]::LocalMachine, [Microsoft.Win32.RegistryView]::Default)
  2. [Microsoft.Win32.RegistryKey]::OpenBaseKey([Microsoft.Win32.RegistryHive]::LocalMachine, [Microsoft.Win32.RegistryView]::Registry32)
  3. [Microsoft.Win32.RegistryKey]::OpenBaseKey([Microsoft.Win32.RegistryHive]::LocalMachine, [Microsoft.Win32.RegistryView]::Registry64)
There is a world of difference between what you see in the 32 bit and the 64 bit. Test your selections to determine which will work best for you.

Also, notice that you still have one more choice to make with respect to the target hive. For

HKEY_CLASSES_ROOT:


[Microsoft.Win32.RegistryKey]::OpenBaseKey([Microsoft.Win32.RegistryHive]::ClassesRoot, [Microsoft.Win32.RegistryView]::Registry32)

HKEY_CURRENT_CONFIG:

[Microsoft.Win32.RegistryKey]::OpenBaseKey([Microsoft.Win32.RegistryHive]::CurrentConfig, [Microsoft.Win32.RegistryView]::Registry32)
HKEY_CURRENT_USER:

[Microsoft.Win32.RegistryKey]::OpenBaseKey([Microsoft.Win32.RegistryHive]::CurrentUser, [Microsoft.Win32.RegistryView]::Registry32)
HKEY_LOCAL_MACHINE:

[Microsoft.Win32.RegistryKey]::OpenBaseKey([Microsoft.Win32.RegistryHive]::LocalMachine, [Microsoft.Win32.RegistryView]::Registry32)

HKEY_USERS:

[Microsoft.Win32.RegistryKey]::OpenBaseKey([Microsoft.Win32.RegistryHive]::Users, [Microsoft.Win32.RegistryView]::Registry32)

Past this, in order to enumerate through the first level of subkeys,

$Names = $regkey.GetSubKeyNames()
foreach($Name in $Names)
{
        #Do something with the key name here
}

In order to open a sub key and then get the sub key names:

$Names = $regkey.OpenSubKey("Software\Microsoft").GetSubKeyNames()
foreach($Name in $Names)
{
        #Do something with the key name here
}

In order to get the Value Names:

$Names = $regkey.GetValueNames()
foreach($Name in $Names)
{
        #Do something with the key name here
}

In order to open a sub key and then get the Value Names of the sub key:

$Names = $regkey.OpenSubKey("Software\Microsoft").GetValueNames()
foreach($Name in $Names)
{
        #Do something with the key name here
}

In order to get the valuekind of a value:

$vkind = $regkey.OpenSubKey("ADODB.Connection\clsid").GetValueKind("")
Assuming you pointed the registrykey to ClassesRoot, this will return
RegistryValueKind.String

Of course, technically, the return value --albeit a string -- is actually a guid. And that enables you to open clsid\{00000514-0000-0010-8000-00AA006D2EA4}\InprocServer32.  Which will point you to the physical location of the file that can be checked for the correct physical file version and internal file version information.














Powershell: Working With The Registry Part3

Here's a script that will populate all the keys in HKEY_CLASSES_ROOT in alphabetical order in an excel spreadsheet:


$oexcel = new-object -comobject Excel.Application
$Workbook = $oexcel.Workbooks.Add()
$oexcel.Visible = $true

$regkey = [Microsoft.Win32.Registry]::ClassesRoot
$Names = $regkey.GetSubKeyNames()
[string]$n
[array]$myvar = [System.Array]::CreateInstance([string], 26)
$myvar[0] = "A"
$myvar[1] = "B"
$myvar[2] = "C"
$myvar[3] = "D"
$myvar[4] = "E"
$myvar[5] = "F"
$myvar[6] = "G"
$myvar[7] = "H"
$myvar[8] = "I"
$myvar[9] = "J"
$myvar[10] = "K"
$myvar[11] = "L"
$myvar[12] = "M"
$myvar[13] = "N"
$myvar[14] = "O"
$myvar[15] = "P"
$myvar[16] = "Q"
$myvar[17] = "R"
$myvar[18] = "S"
$myvar[19] = "T"
$myvar[20] = "U"
$myvar[21] = "V"
$myvar[22] = "W"
$myvar[23] = "X"
$myvar[24] = "Y"
$myvar[25] = "Z"
$workbook.Worksheets.Add()
$workbook.Worksheets.Add()
$workbook.Worksheets.Add()
$workbook.Worksheets.Add()
$workbook.Worksheets.Add()
$workbook.Worksheets.Add()
$workbook.Worksheets.Add()
$workbook.Worksheets.Add()
$workbook.Worksheets.Add()
$workbook.Worksheets.Add()
$workbook.Worksheets.Add()
$workbook.Worksheets.Add()
$workbook.Worksheets.Add()
$workbook.Worksheets.Add()
$workbook.Worksheets.Add()
$workbook.Worksheets.Add()
$workbook.Worksheets.Add()
$workbook.Worksheets.Add()
$workbook.Worksheets.Add()
$workbook.Worksheets.Add()
$workbook.Worksheets.Add()
$workbook.Worksheets.Add()
$workbook.Worksheets.Add()
$workbook.Worksheets.Add()
$workbook.Worksheets.Add()

    $sheet = $workbook.worksheets.Item(1)
    $sheet.name = "A"
    $sheet = $workbook.worksheets.Item(2)
    $sheet.name = "B"
    $sheet = $workbook.worksheets.Item(3)
    $sheet.name = "C"
    $sheet = $workbook.worksheets.Item(4)
    $sheet.name = "D"
    $sheet = $workbook.worksheets.Item(5)
    $sheet.name = "E"
    $sheet = $workbook.worksheets.Item(6)
    $sheet.name = "F"
    $sheet = $workbook.worksheets.Item(7)
    $sheet.name = "G"
    $sheet = $workbook.worksheets.Item(8)
    $sheet.name = "H"
    $sheet = $workbook.worksheets.Item(9)
    $sheet.name = "I"
    $sheet = $workbook.worksheets.Item(10)
    $sheet.name = "J"
    $sheet = $workbook.worksheets.Item(11)
    $sheet.name = "K"
    $sheet = $workbook.worksheets.Item(12)
    $sheet.name = "L"
    $sheet = $workbook.worksheets.Item(13)
    $sheet.name = "M"
    $sheet = $workbook.worksheets.Item(14)
    $sheet.name = "N"
    $sheet = $workbook.worksheets.Item(15)
    $sheet.name = "O"
    $sheet = $workbook.worksheets.Item(16)
    $sheet.name = "P"
    $sheet = $workbook.worksheets.Item(17)
    $sheet.name = "Q"
    $sheet = $workbook.worksheets.Item(18)
    $sheet.name = "R"
    $sheet = $workbook.worksheets.Item(19)
    $sheet.name = "S"
    $sheet = $workbook.worksheets.Item(20)
    $sheet.name = "T"
    $sheet = $workbook.worksheets.Item(21)
    $sheet.name = "U"
    $sheet = $workbook.worksheets.Item(22)
    $sheet.name = "V"
    $sheet = $workbook.worksheets.Item(23)
    $sheet.name = "W"
    $sheet = $workbook.worksheets.Item(24)
    $sheet.name = "X"
    $sheet = $workbook.worksheets.Item(25)
    $sheet.name = "Y"
    $sheet = $workbook.worksheets.Item(26)
    $sheet.name = "Z"

for($x=0;$x -lt $myvar.GetLength(0);$x++)
{
         
    $sheet = $workbook.worksheets.Item($x+1)
    $y = 0
    foreach($Name in $Names)
    {
        $pos = $Name.IndexOf($myvar[$x])
        if($pos -eq 0)
        {
            $sheet.cells.item($y+1,1) = $Name
            $y=$y+1
        }
    } 
   
    $oexcel.Columns.HorizontalAlignment = -4131
    $iret = $oexcel.Columns.AutoFit()    
}

Powershell: Creating a Process in a Hidden Window Processes


This script Demonstrates how to create a hidden window while launching an instance of Notepad.
 

 ([wmiclass]"Win32_Process").Create("notepad")
 
How Much easier can it get? 
 

Wednesday, July 30, 2014

Powershell and event providers

When you write:

Select * From __InstanceCreationEvent WITHIN 1 where target instance ISA 'Win32_Process'"

What does that really mean?

  1. It means that when a Win32_Process Class gets created, you get notified.
  2. It means that when an __InstanceCreationEvent Class is used, you get notified.
  3. None of the above
  4. All of the above -- including None of the above
  5. All of the above -- excluding 3 and 4
  6. I'm as confused as you are, ACE, so let's crash and burn together.
Truth, an event provider is there to help us get notified when something happens. There's a whole lot of events that happen within the world of Windows and WMI.

__InstanceOperationEvent
__InstanceModificationEvent
__InstanceCreationEvent
__MethodInvocationEvent
__InstanceDeletionEvent

__ClassOperationEvent
__ClassDeletionEvent
__ClassModificationEvent
__ClassCreationEvent

__NamespaceOperationEvent
__NamespaceModificationEvent
__NamespaceDeletionEvent
__NamespaceCreationEvent

__TimerEvent
__ExtrinsicEvent
__SystemEvent

__EventDroppedEvent
__EventQueueOverflowEvent

__QOSFailureEvent
__ConsumerFailureEvent


Powershell: Creating easy to read tabular output

This one is going to be quick and to the point.

If you have been writing VBScripts and the like, you know, in order to block columns of information, by finding the max length of the entry and then use that against the length of each item:

       L = 120
      For each prop in obj.Properties_
         txtstream.WriteLine(Prop,Name & spaces(L - len(prop.Name)) & nextvalue
     Next

Of course the above is a pretty bad example.  But you get the Idea.  Get the longest length and then add padding to the right using the space function to add the number of spaces need so that the next value would start at exactly the same location.

In .Net and using power shell:

foreach($prop in $obj.Proeprties_)
{
      $txtstream.WriteLine("$prop.Name.ToString.Paddright 120, " ") + $nextValue
}

And it is done.




 

Sunday, July 27, 2014

Powershell: Working with the registry Part 1

Second to Windows Management Instrumentation, the registry is one of the most powerful tools you have as a potential money making skill set. It is also be one of the most dangerous and less understood tools of the trade.

With that said, let's jump right in.

HIVES

Sections of the registry are known as hives. The five most popular are:

  1. HKEY_CLASSES_ROOT
  2. HKEY_CURRENT_CONFIG
  3. HKEY_CURRENT_USER
  4. HKEY_LOCAL_MACHINE
  5. HKEY_USERS
Prior to .Net, you had to know each of those as constants where and you had to the APIs needed to use them. With .Net, the ability to connect to the registry is as simple as this:
 

$regkey = [Microsoft.Win32.Registry]::ClassesRoot
[array]$Names = $regkey.OpenSubKey("DataLinks").GetSubKeyNames()
foreach($n in $Names)

{
write-host $n
}

This returns: CLSID
 

I add this to the Datalinks subkey and make the call again:

[string]$Value = $regkey.OpenSubKey("DataLinks\CLSID").GetValue("")
write-host $value


And this returns:
 

{2206CDB2-19C1-11D1-89E0-00C04FD7A829}



I can then go to the clsid section and glean information about the location of the file:

[string]$value = $regkey.OpenSubKey("clsid\{2206CDB2-19C1-11D1-89E0-00C04FD7A829}\InprocServer32").GetValue("")

And that returns:

C:\Program Files\Common Files\System\Ole DB\oledb32.dll