Skip to main content

Useful Powershell stuff

Use "PipelineVariable" to pass data down the pipeline rather than using a foreach:

Get-ADUser <username> -PipelineVariable user -Properties memberof |
    Select-Object -ExpandProperty memberof |
        Select-Object @{ n = 'Name'; e = { $user.Name }}, @{ n = 'MemberOf' ; e = { $PSItem -replace 'CN=|,(OU|CN)=.+' }}

Also if a cmdlet does not support -pipelineVariable you can pass it to Where-Object

Get-Mailbox -ResultSize Unlimited | Where-Object {$true} -PipelineVariable mbx | whatever


Convert a list of strings into a single line string delimited by quotes and separated by commas, suitable for using in a "IN" statement in SQL/SOQL

$ids is a list of ID strings
$idsString = $ids -replace "(\w+)",'''$1'''  -join ','
or if it's one large string separated by line breaks (e.g. copied from a spreadsheet):
$idsString = ($ids -replace "(\w+)",'''$1''').Split("`n") -join ','


Print a line
'_' * 100

Prevent null references, incorrect syntax usage, unnamed variables:
Set-StrictMode -Version Latest

Creating a new instance of a .net framework object
New-Object TypeName "System.Diagnostics.Stopwatch"
Or more simply, New-Object System.Diagnostics.Stopwatch
Because it's a string, don't use the type name in angle brackets like PS normally would

To view absolutely everything that's happening internally in the powershell pipeline for a particular scriptblock:
Trace-Command -Name * -Expression {Get-Service winrm | Restart-Service} -PSHost

Add a calculated property to a list of objects, along with all the other properties:
    Select *,@{Name="ExtraField"; Expression={$_.SomeValue+1}}, @{Name="Whatever"; Expression={"Some string"}}

Get a list of drives, including network drives and their UNC paths (like with "net use"):
    Get-WmiObject -Class win32_logicaldisk

Get previous session history with "get-history"
Run a previous command without pushing up 1000 times with "invoke-history"

csi = C# interactive (custom alias)

Formatting:
get a list of every property and value for an object:
    $whatever | Format-List
Prevent output from truncating:
    Format-Table -AutoSize -Wrap

Redirection:
& { blah } 1 > $null    - suppress standard output from executing "blah". More info
$var = & Do-Stuff *>&1  - redirect all output to standard output and store that in $var
& { whatever } 2>$null 3>$null - redirect error and warning streams

Output:
get-content .\somefile -Wait  - tail-like behaviour, displays additions to the file
get-content | more  - allows paging of output

Getting a count of duplicated things:
$whatever | group FieldToGroup | where Count -gt 1 | sort Count -Descending | select Name, Count

set-clipboard (scb) - sets the contents of the clipboard to whatever is pasted in.  Useful with sls for non-powershell commands that output text that you have to use in another command

Delimiters
`t - tab

When using delimiters with "Import-Csv -Delimiter", make sure not to surround them with quotes

cd env:    gets environment vars
get-psprovider    lists providers
get-psdrive    lists drives
get-module -listavailable    lists all available modules

hashtable of variables for passing in parameters
$parameters = @{
    'param1' = $value1
    'param2' = $value2
}

Run-SomeCmdlet @parameters     <- notice the @ symbol, not $

write-verbose lines in a function only write if a -verbose flag was provided to the function

@($a) forces $a to be in an array

use regexes with "where" with the "match" operator:
    gci | where name -match '\d{2}'

rename properties for a select:
        ps | select @{Name='Title';Exp={$_.ProcessName}}

select-string (alias: sls)
    very useful for selecting strings from a whole bunch of string-based output
    works like grep in linux
        ipconfig | sls subnet

To use IIS stuff:
    Import-Module WebAdministration
open IIS drive and navigate to a website:
    cd IIS:\
    cd sites\sitename

Get a list of every module
    Get-Module -ListAvailable
Find a module based on name
    Get-Module *web*
Find all commands in a module
    Get-Command -Module WebAdministration

get current item members:
    gi . | gm
recycle an app pool by navigating to it
    cd IIS:\AppPools\somewebsite
    (gi .).Recycle()
or also in one line:
    (gi IIS:\AppPools\somewebsite).Recycle()

ii (invoke-item)
    performs the default action on an item, e.g. opens a file using a program

-join operator, joins strings together
    when used first (unary), joins without delimiting
        -join ("asdf", "qwer") #outputs asdfqwer
    when used as a binary operator, allows a delimiter
        ("asdf", "qwer") -join '-' #outputs asdf-qwer

-replace operator, using regex to replace strings
    replace pairs of html tags with <small>:
        $foo = $foo -replace '<(\/)?\w+>', '<$1small>'

searching application event log for a particular guid:
    Get-EventLog -logname application | where {$_.Message -ilike "*6CD27361-D038-E611-9B7F-005056956605*") } | select message

Comments

Popular posts from this blog

"A section using 'configSource' may contain no other attributes or elements" error after installing Application Insights

After installing the Application Insights nuget package to an Umbraco solution, you'll get this error:

A section using 'configSource' may contain no other attributes or elements

<ExamineLuceneIndexSets configSource="config\ExamineIndex.config" />
     <log4net configSource="config\log4net.config">
         <root>
             <level value="ALL" />
             <appender-ref ref="aiAppender" />
Source File: \project\web.config

This happens because part of the Application Insights installation process adds a <log4net> section to web.config.  Which would make sense, except Umbraco already has a <log4net> section in /config/log4net.config.  So as you can imagine, the solution is to manually move everything its added into that file. Unfortunately you can't just copy/paste the whole lot, but it's not particularly complicated:


Move <appender-ref ref="aiAppender" /> into the lo…

Using WiX to create an event source during install of a .NET framework project

Edit: so I guess I wasn't the only one confused with this stuff, as it's been my most popular post by far!  If I've helped you out or saved you some time, please let me know in the comments :)

In order for this to work, you have to add references to WixUtilExtension and WixNetFxExtension to your WiX project.  Once that's done, add this inside a <Component> element:

<Util:EventSourcexmlns:Util="http://schemas.microsoft.com/wix/UtilExtension"Name="EVENTSOURCEGOESHERE"Log="Application"EventMessageFile="[NETFRAMEWORK40FULLINSTALLROOTDIR]EventLogMessages.dll" />
Obviously replace EVENTSOURCEGOESHERE with your event source name.  NETFRAMEWORK40FULLINSTALLROOTDIR is a property set by the WixNetFxExtension which stores the path to the .NET framework v4 directory, but you can replace this with the corresponding property for the directory containing the relevant EventLogMessages.dll file.  So if you're using the .NET framewo…

How to make yourself a Dynamics CRM 2011 Deployment Administrator

Today I needed to deactivate one of our Dynamics organisations, but when I opened the Dynamics Deployment Manager, I received the following error:

"Only the Deployment Administrators are able to use Deployment Manager. You are not a Deployment Administrator."
Bummer. I did a bit of Googling and found this post by Ronald Lemmen (thanks for pointing me in the right direction!).  Since the Dynamics Deployment Manager is obviously checking the MSCRM_CONFIG database for this information I attached a database trace to it and found that it's executing these queries (among many others):

exec sp_executesql N'SELECT  Id, [DefaultOrganizationId], [IsDisabled], [Name]   FROM [SystemUser]   WHERE ((([Name] = @Name0)) ) AND (IsDeleted = 0) ', N'@Name0 nvarchar(41)',@Name0=N'{My windows domain account}'
exec sp_executesql N'SELECT  Id, [Name], [UniqueifierId]   FROM [SecurityRole]   WHERE ((([Name] = @Name0)) ) AND (IsDeleted = 0) ', N'@Name0 nvarchar…