Windows PowerShell

Misc commands

Setting NTFS permissions with PowerShell http://blogs.technet.com/b/josebda/archive/2010/11/12/how-to-handle-ntfs-folder-permissions-security-descriptors-and-acls-in-powershell.aspx

Using the replace operator with regular expressions, note the use of the `

"Hello Stephen" -replace "^Hello (.+)$", "Goodbye `$1"

Passing an array to a constructor http://stackoverflow.com/questions/12870109/how-do-i-call-new-object-for-a-constructor-which-takes-a-single-array-parameter

$certString = "MIIDT....."
$certBytes = [System.Convert]::FromBase64String($certString)
$cert = [System.Security.Cryptography.X509Certificates.X509Certificate2] $certBytes

Listing Windows Updates with PowerShell

Taken from a very useful article: http://social.technet.microsoft.com/wiki/contents/articles/4197.how-to-list-all-of-the-windows-and-software-updates-applied-to-a-computer.aspx. The code is copied here in case the page gets removed.

Standard listing using WMI

Get-WmiObject -Class "win32_quickfixengineering" |
Select-Object -Property "Description", "HotfixID", @{Name="InstalledOn"; Expression={([DateTime]($_.InstalledOn)).ToLocalTime()}}

To get a list of hotfixes to transport to another system the PowerShell fragment below prints a command that can be executed on the remote system.

'$hotfixes = @("{0}")' -f ((Get-WmiObject win32_quickfixengineering | % {$_.HotFixID}) -join '","')

Full listing of updates

$Session = New-Object -ComObject "Microsoft.Update.Session"
$Searcher = $Session.CreateUpdateSearcher()
$historyCount = $Searcher.GetTotalHistoryCount()
$Searcher.QueryHistory(0, $historyCount) | Select-Object Title, Description, Date,
    @{name="Operation"; expression={switch($_.operation){
        1 {"Installation"}; 2 {"Uninstallation"}; 3 {"Other"}
}}}

Installed products

To get installed products:

Get-WmiObject win32_product | sort Vendor,Name | ft -Wrap -AutoSize Version,Name -GroupBy Vendor
dir HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\ | % {$_.OpenSubkey($_.Path).GetValue("DisplayName")}

IIS Management with PowerShell

Exchange management

Taken from http://social.technet.microsoft.com/Forums/office/en-US/c5473bde-53fc-404c-89af-4d3dd112a084/get-list-of-users-in-c-code-who-has-mailbox-access-permissions-to-particular-user?forum=exchangesvrgeneral (I have not validated this code fragment).

SecureString password = new SecureString();
string str_password = "xxxxx";
string username = "Administrator@admin.com";
foreach (char x in str_password) { password.AppendChar(x); }
PSCredential credential = new PSCredential(username, password);

WSManConnectionInfo connectionInfo = new WSManConnectionInfo(new Uri("http://ExchangeServer.admin.com/powershell/Microsoft.Exchange"), "http://schemas.microsoft.com/powershell/Microsoft.Exchange", credential);

Runspace runspace = RunspaceFactory.CreateRunspace(connectionInfo);

PowerShell powershell = PowerShell.Create();

PSCommand command = new PSCommand();
command.AddCommand("Get-Mailbox");
command.AddParameter("ResultSize", int.MaxValue);
powershell.Commands = command;
runspace.Open();
powershell.Runspace = runspace;
Collection usersList = powershell.Invoke();
runspace.Close();

Authenticated web request

The following fragment is useful for testing, both injecting credentials into a web request and ignoring certificate validation failures (this must only be used for testing/diagnostic purposes):

$url = "https://«host»/«path»"
$account = "«domain»\«username»"

if ($password -eq $null) {$password = read-host -AsSecureString "Enter password for $account"}

$source = @"
using System.Net;
using System.Net.Security;
using System.Security.Cryptography.X509Certificates;

public static class CustomCertificateValidationCallback {
    public static void Install() 
    {
        ServicePointManager.ServerCertificateValidationCallback += CustomCertificateValidationCallback.CheckValidationResult;
    }

    public static bool CheckValidationResult(
        object sender, 
        X509Certificate certificate, 
        X509Chain chain, 
        SslPolicyErrors sslPolicyErrors)
    {
        // please don't do this. do some real validation with explicit exceptions.
        return true;
    }
}
"@
Add-Type -TypeDefinition $source -Language CSharp
[CustomCertificateValidationCallback]::Install()

[System.Reflection.Assembly]::LoadWithPartialName("System.Net") > $null
[System.Reflection.Assembly]::LoadWithPartialName("System.Net.Http") > $null
$cred = New-Object System.Net.NetworkCredential -ArgumentList $account,$password
$handler = New-Object System.Net.Http.HttpClientHandler
$handler.Credentials = $cred
$handler.PreAuthenticate = $True
$httpclient = New-Object System.Net.Http.HttpClient -ArgumentList $handler
$httpclient.GetAsync($url).Result

Windows Features

# Get a list of windows features to install on another system
(Get-WindowsFeature | ? {$_.Installed} | ? {$_.SubFeatures.Length -Eq 0} | % {$_.Name}) -Join ","

PowerShell Command History File

$env:APPDATA\Microsoft\Windows\PowerShell\PSReadLine\ConsoleHost_history.txt

Automating Remote Desktop configuration

Turning on Remote Desktop automatically, includes updating Remote Desktop User group: http://blogs.msdn.com/b/matthew_van_eerde/archive/2012/03/15/unattend-xml-turning-on-remote-desktop-automatically.aspx

Configuring the filrewall in unattend file – includes setting for key: http://technet.microsoft.com/en-us/library/dd744354(v=ws.10).aspx

Disabling network level authentication http://blogs.msdn.com/b/rds/archive/2007/03/21/enabling-remote-desktop-using-unattended-setup.aspx

Certificates

Select certificate for desktop services:

wmic /namespace:\\root\cimv2\TerminalServices PATH Win32_TSGeneralSetting Set SSLCertificateSHA1Hash=""

Hyper-V scripts and resources

http://social.technet.microsoft.com/wiki/contents/articles/176.hyper-v-scripts.aspx

PowerShell to mount CD in virtual machine

Get virtual host information from guest:

get-itemproperty 'HKLM:\SOFTWARE\Microsoft\Virtual Machine\Guest\Parameters'

Get virtual machine system information through PowerShell

$vmname = "xxx"
$SysInfo = Get-WmiObject -Class Msvm_VirtualSystemSettingData -Namespace Root\virtualization | ? {$_.ElementName -eq $vmname}

Re-attach virtual machines where no export has been performed http://eniackb.blogspot.co.uk/2009/05/how-to-recover-hyper-v-virtual-machine.html

$newVMLocation="J:\Hyper-V\Machines"
foreach($nextGuid in Get-ChildItem ("{0}\Virtual Machines" -f $newVMLocation) -Name *.xml | % {$_ -replace "^(.*)\.xml$","`$1"})
{
	$linkName = ("C:\ProgramData\Microsoft\Windows\Hyper-V\Virtual Machines\{0}.xml" -f $nextGuid)
	$xmlName = ("{0}\Virtual Machines\{1}.xml" -f $newVMLocation,$nextGuid)
	if (-Not (Test-Path $linkName))
	{
		$linkCommand = ('cmd /c mklink "{0}" "{1}"' -f $linkName, $xmlName)
		Invoke-Expression $linkCommand

		icacls `"$linkName`" /grant `"NT VIRTUAL MACHINE\$nextGuid`"`:`(F`) /L

		icacls `"$newVMLocation`" /T /grant `"NT VIRTUAL MACHINE\$nextGuid`"`:`(F`)
	}
}

Get machine serial number & name

wmic bios get serialnumber
wmic csproduct get name, identifyingnumber