PowerShell – Array vs. ArrayList Performance

Let’s take a look at performance when dealing with looping over an array variable; adding a new item and overall performance.
A standard array object in PowerShell is of a fixed size when created and cannot expand automatically. When you use the “+=” operator to append an entry, a new array object is created in memory with the additional overall previous array object. This leads to a large performance hit when dealing with a large number of items and increased memory consumption. For example:


$ArrayList = New-Object -TypeName 'System.Collections.ArrayList';
$Array = @();


Measure-Command
{
for($i = 0; $i -lt 10000; $i++)
{
$null = $ArrayList.Add("Adding item $i")
}
};
Measure-Command
{
for($i = 0; $i -lt 10000; $i++)
{
$Array += "Adding item $i"
}
};

Recommendation: use generics!

PowerShell – Single Quote vs. Double Quote

What’s the difference with quotes?

Single quote: It is taken literally and provided back.
Double quotes: PowerShell looks for the $ character inside of the double quotes. Once found, it assumes the following characters are the name of a variable up to the first space, is a variable name.

Sample:

[System.String]$a = 'Hello'
$b = '$a World!'
# $b prints: $a World!
$c = "$a World!"
# $c prints: Hello World!

Modifying Multivalued Attributes With PowerShell

[int] $ADS_PROPERTY_CLEAR = 1;
[int] $ADS_PROPERTY_UPDATE = 2;
[int] $ADS_PROPERTY_APPEND = 3;
[int] $ADS_PROPERTY_DELETE = 4;

# Get the user's Distinguished Name (DN) however you prefer.
# Utilize the above option switch to adjust.
$ADuser = [ADSI]"LDAP://SERVER-NAME-HERE/$($theUserAccount.DistinguishedName)"          
$ADuser.PutEx($ADS_PROPERTY_DELETE, "proxyAddresses", @("smtp:$userNameForUpdate@contoso.com"))
$ADuser.PutEx($ADS_PROPERTY_APPEND, "proxyAddresses", @("SMTP:$userNameForUpdate@extranet.contoso.com"))

# Commit the changes to the AD User Object:
$ADuser.SetInfo()

Reference:
http://technet.microsoft.com/en-us/library/ee156515.aspx

More Debian Adventures

Tried a NetBoot install of Debian and was a big fan of this post: http://www.octatech.net/blog/2014/08/things-to-do-after-installing-debian-8-jessie/

The NIC in my NUC wasn’t auto-detected initially and had to use a Debian Unstable net-boot image as mentioned in this post:
http://codepoets.co.uk/2014/installing-debian-jessie-on-an-intel-nuc-d54250wyk/

PowerShell – Check For Matching Items In Seperate Arrays

$test1 = (1,2,3)
$test2 = (2,4,6)
$test3 = (1,3,5)
( ( $test1 + $test2 + $test3) | Group-Object |?{$_.Count -gt 1}).Values

Example outputs:

PS C:\> $test1 = (1,2,3)
$test2 = (2,4,6)
$test3 = (1,3,5)
( ( $test1 + $test2 + $test3) | Group-Object |?{$_.Count -gt 1}).Values
1
2
3
PS C:\>  

PowerShell Special Characters and Tokens (short-handing):
http://www.neolisk.com/techblog/powershell-specialcharactersandtokens

PowerShell – Registry & File System Access Control Lists (ACL) Creation

#
# File system:
# http://msdn.microsoft.com/en-us/library/system.security.accesscontrol.filesystemaccessrule(v=vs.110).aspx
#
# Name of the user or group:
$objIdentityReference = [System.Security.Principal.NTAccount]("HOSTNAME\username")
# Rights to assign. List: http://msdn.microsoft.com/en-us/library/system.security.accesscontrol.filesystemrights(v=vs.110).aspx
$objFileSystemRights = [System.Security.AccessControl.FileSystemRights]"Read,Write"
# Permission inheritance: None, ContainerInherit, Object Inherit
$objInheritanceFlags = [System.Security.AccessControl.InheritanceFlags]::None
# Propagation of permissions: None, InheritOnly, NoPropagateInherit
$objPropagationFlags = [System.Security.AccessControl.PropagationFlags]::None
# Allow or Deny:
$objAccessControlType = [System.Security.AccessControl.AccessControlType]::Allow
# Create new rule:
$objRule = New-Object System.Security.AccessControl.FileSystemAccessRule ($objIdentityReference, $objFileSystemRights, $objInheritanceFlags, $objPropagationFlags, $objAccessControlType)
$objACL = Get-ACL "C:\TestFolder"
# Add our new rule:
$objACL.AddAccessRule($objRule)
# Set the new permissions:
Set-ACL "C:\Path\To\Folder" $objACL

# Alternatively, create your rule list manually:
$AclRuleList = New-Object System.Security.AccessControl.DirectorySecurity
$AclRuleList.AddAccessRule($objRule)
$AclRuleList.SetOwner([System.Security.Principal.NTAccount]"Administrators")
# http://msdn.microsoft.com/en-us/library/system.security.accesscontrol.objectsecurity.setaccessruleprotection(v=vs.110).aspx
$AclRuleList.SetAccessRuleProtection($true,$false) #isProtected,preserveInheritance

#
# Registry:
# http://msdn.microsoft.com/en-us/library/system.security.accesscontrol.registryaccessrule(v=vs.110).aspx
#
# Name of the user or group:
$objIdentityReference = [System.Security.Principal.NTAccount]("HOSTNAME\username")
# Rights to assign. List: http://msdn.microsoft.com/en-us/library/system.security.accesscontrol.registryrights(v=vs.110).aspx
$objRegistryRights = [System.Security.AccessControl.RegistryRights]::FullControl
# Permission inheritance: None, ContainerInherit, Object Inherit
$objInheritanceFlags = [System.Security.AccessControl.InheritanceFlags]::None
# Propagation of permissions: None, InheritOnly, NoPropagateInherit
$objPropagationFlags = [System.Security.AccessControl.PropagationFlags]::None
# Allow or Deny:
$objAccessControlType = [System.Security.AccessControl.AccessControlType]::Allow

# Create your new rule:
$objRule = New-Object System.Security.AccessControl.RegistryAccessRule ($objIdentityReference, $objRegistryRights, $objInheritanceFlags, $objPropagationFlags, $objAccessControlType)
$objACL = Get-ACL "HKCU:\TEST"
# Add our new rule:
$objACL.AddAccessRule($objRule)
# Set the new permissions:
Set-ACL "HKCU:\TEST" $objACL

# Alternatively, create your rule list manually:
$AclRuleList = New-Object System.Security.AccessControl.RegistrySecurity
$AclRuleList.AddAccessRule($objRule)
$AclRuleList.SetOwner([System.Security.Principal.NTAccount]"Administrators")
$AclRuleList.SetAccessRuleProtection($true,$false)

WMIC, WmiObject, CimInstance Formatting

wmic bios get serialnumber

Reference: http://support.microsoft.com/kb/558124

New formats:

Get-WmiObject -Class "Win32_SystemEnclosure" | Select-Object SerialNumber
# OR
Get-CimInstance -Class "Win32_SystemEnclosure" | Select-Object SerialNumber

Another type of Query:

Get-WmiObject -Query "SELECT * FROM Win32_ComputerSystem" -ComputerName .
# OR
Get-CimInstance -Query "SELECT * FROM Win32_ComputerSystem" -ComputerName .

PowerShell – Dissecting Parameters and Enumeration

Get-Command Get-Mailbox | Get-Member Param*
(Get-Command Get-Mailbox).Parameters | Format-List
(Get-Command Get-Mailbox).ParameterSets | Format-List name # Returns: __AllParameterSets
$m = (Get-Command Get-Mailbox).ParameterSets[0].Parameters | ?{$_.Name -eq "Filter"}

References:

http://blogs.msdn.com/b/powershell/archive/2006/05/10/594175.aspx

 

 

Enumeration:

function Select-Color
{
  param(
  [System.ConsoleColor]
  $Color
  )

  "You chose $Color"
}

Then enter: Select-Color -Color
Snippet from:
http://powershell.com/cs/blogs/tips/archive/2012/11/16/using-enumeration-types-for-parameter-intellisense.aspx
References:
http://blogs.msdn.com/b/powershell/archive/2007/01/23/how-to-create-enum-in-powershell.aspx

PowerShell – Dispose()

You may be asking yourself “Why is that one script keeping all my RAMs?!”.

Maybe you should call the .Dispose() method on the variable to clean-up.

Another option is to use Remove-Variable .

References:
http://technet.microsoft.com/en-us/library/ff730962.aspx
http://msdn.microsoft.com/en-us/library/system.management.automation.powershell.dispose(v=vs.85).aspx