Powershell

Powershell first and last day of this month and last

0

$CURRENTDATE=GET-DATE -Format “MM/dd/yyyy”
$FIRSTDAYOFTHEMONTH = GET-DATE $CURRENTDATE -Day 1
$LASTDAYOFTHEMONTH = GET-DATE $FIRSTDAYOFTHEMONTH.AddMonths(1).AddSeconds(-1)
$LASTDAYOFLASTMONTH = GET-DATE $FIRSTDAYOFTHEMONTH.AddMonths(0).AddSeconds(-1)

$FIRSTDAYOFTHEMONTH
$LASTDAYOFTHEMONTH
$LASTDAYOFLASTMONTH

$CURRENTMONTH = GET-DATE -Format “MMyyyy”
$CURRENTMONTH

SharePoint 2010 Retrieve All User Group Memberships

0

To view a list of all groups and user memberships for a certain SharePoint 2010 site collection try this PowerShell script. Be sure to change the name of the SharePoint site in the script under the $site variable.


[System.Reflection.Assembly]::LoadWithPartialName("Microsoft.SharePoint")
$site = New-Object Microsoft.SharePoint.SPSite("http://server/sites/sitecollectionname")
$groups = $site.RootWeb.sitegroups
foreach ($mygroup in $groups)
{
"Group: " + $mygroup.name;
foreach ($user in $mygroup.users)
{
" User: " + $user.name
}
}
$site.Dispose()

Enabling Remote WMI and DCOM by Command Line on Remote Computer

0

Enabling Remote WMI and DCOM for PowerShell Use
Many cmdlets have a built-in -ComputerName parameter that will allow for remote access without using the new PowerShell remoting. For this to work, your firewall will need to be adjusted on the target machine:
netsh firewall set service type = remoteadmin mode = enable
In addition, some cmdlets (like Get-Service) will need the Remote Registry service to be running on the target side:
Start-Service RemoteRegistry
Set-Service RemoteRegistry -StartupType Automatic

SharePoint 2010 PowerShell – List all timer job history a certain time range to CSV file

1

Since we wrote this script it has helped us get info about specific jobs really quickly. You can download this script here: SharePoint 2010 – Get Job History or copy it here:


cls
$test = Get-SPWebApplication "http://intranet/"
$myStartTime = "9/29/2011 12:30:00 AM"
$myStopTime = "9/29/2011 3:30:00 AM"


#GET ALL BETWEEN THAT TIME PERIOD
Write-Host "Fetching all jobs to JobHistoryOutput.csv for $myStartTime - $myStopTime..." -ForeGroundColor Red
$test.JobHistoryEntries | Where-Object {($_.StartTime -gt $myStartTime) -and ($_.StartTime -lt $myStopTime)} | Export-Csv JobHistoryOutput.csv –NoType
Write-Host "Done! Check JobHistoryOutput.csv for info." -ForeGroundColor Green


#GET ALL THAT FAILED BETWEEN THAT TIME PERIOD
Write-Host "Fetching all errors to JobHistoryOutputErrors.csv for $myStartTime - $myStopTime..." -ForeGroundColor Red
$test.JobHistoryEntries | Where-Object {($_.StartTime -gt $myStartTime) -and ($_.StartTime -lt $myStopTime) -and ($_.Status -ne 'Succeeded')} | Export-Csv JobHistoryOutputErrors.csv –NoType
Write-Host "Done! Check JobHistoryOutputErrors.csv for info." -ForeGroundColor Green



Retreiving SharePoint 2010 Jobs Details by Date and Time
1. Log onto your SharePoint 2010 application server with farm admin rights.
2. Run SharePoint Admin Shell.
3. Change the SharePoint application in the script on line 2 (mine was http://intranet). Change the dates and times in the scriptlines 3 and 4.
4. Run the script as shown below:

5. View output from the script:

6. You’ll get two files. C:\JobHistoryOutput.csv is all jobs. C:\JobHistoryOutputErrors.csv is jobs that didn’t get a “Succeeded” status. Sort and filter in excel for the results you want: JobDefinitionId, JobDefinitionTitle, WebApplicationId, WebApplicationName, ServiceId, ServerId, ServerName, Status, StartTime, EndTime, DatabaseName, ErrorMessage

Powershell to Get the count of user objects in Active Directory using LDAP Query

0

$Domain = ‘LDAP://DC=yourdomain;DC=com’
$Root = New-Object DirectoryServices.DirectoryEntry $Domain
$select = New-Object DirectoryServices.DirectorySearcher
$select.SearchRoot = $root
$adobj= $select.findall() |? {$_.properties.objectcategory -match “CN=Person”}
$adobj.count

For the $Domain variable change the “yourdomain” string to the name of your domain.

Fake a schedule using PowerShell jobs with the Start-Sleep cmdlet

0

Here’s one way to fake a schedule using jobs with the Start-Sleep cmdlet. Let’s say I want to start a job at 19:43:00. You could probably pass dates as well, though. Just place your script name/commands instead of the “Executed!” string.


PS U:\bin> Start-Job -Name USCase98765 -ScriptBlock {Start-Sleep -Seconds ([int]((New-TimeSpan -Start (Get-Date) -End (Get-Date -Hour 19 -Minute 43 -Second 0)).TotalSeconds)); `
(Get-Date);"Executed!"}


Id Name State HasMoreData Location Command
-- ---- ----- ----------- -------- -------
3 USCase98765 Running True localhost Start-Sleep -Seconds (...
PS U:\bin> Receive-Job -Name USCase98765
Thursday, October 28, 2010 7:43:00 PM
Executed!

Powershell

0

One of the most important first steps to know about powershell is how to disable the security policy so you can just get into learning it. This command:
Set-ExecutionPolicy Unrestricted
will disable the default security policy.

Some introductory examples to get your feet wet (copy one of the two below lines from the browser then right click in the windows power shell run time to paste):

get-EventLog system -newest 2000 | where {$_.entryType -match “Software”}
get-EventLog system -newest 2000 | where {$_.message -match “Software”}

Here is how you find out which processes have been started in the last hour (both lines on code below):
$1HourAgo = [DateTime]::Now.AddHours(-1)
Get-Process -computer spkwrkdaveh |where {$_.StartTime -ge $1HourAgo}

This command gets all of the errors in the Windows PowerShell event log that occurred in June 2008 (all three lines on code below):
$May31 = get-date 5/31/08
$July1 = get-date 7/01/08
get-eventlog -log “Windows PowerShell” -entrytype Error -after $may31 -before $july1

If Statement

As with so many PowerShell constructions, the type of bracket signifies how to break the script into sections.  It is worth emphasising that (parenthesis are for the first part, the condition), while {braces are for the block command}.

If (condition) {Do stuff}
or an alternative explanation would be
If (test) {execute if true}

$Number = 10
if ($Number -gt 0) {“Bigger than zero”}

Learning Points

Note 1: Trace the construction and separate into: if (test) and {what to do}.

Note 2: Avoid over-think; there is no ‘Then’ in PowerShell’s ‘If’ statement.  My advice is that instead of worrying about ‘Then’, pay close attention to the two types of bracket.

Note 3: To double check your understanding, try amending, “Bigger than Zero” to a different text string, such as:  “Less than nought”.  Once you have done that, set $Number to -1.

Example 1a File Content Example of Plain ‘If’

PowerShell has a batch of help files.  One of these files contains help about the ‘if’ statement.   In the example below, $File references that file.  $Content is set to the content of the file.  The third line attempts to match a string to the contents of the file.

# Help on PowerShell’s if statements
$File = get-Help about_if
if ($File -match “The if Statement”) {“We have the correct help file”}

Learning Points

This example is concerned with matching a string “The if Statement” to the contents of a file.

# Help on PowerShell’s if statements
$File = get-Help about_if
if ($File -match “The if Statement”) {“We have the correct help file”}
Else {“The string is wrong”}

Learning Points

The best way to see how ‘else’ operates is to amend line 3 thus:
($File -match “The ifzz Statement”).

Example 3 ElseIf

This example has a real task, and that is to check that we have the name of an actual file.

# Help on PowerShell’s if statements
$File = get-Help about_if
if ($File -match “The if Statement”) {“We have the correct help file”}
ElseIf ($File.Length -lt 1) {“Check file location”}
Else {“File exists, but does not contain text string”}

Learning Points

Note 1: The advantage of ElseIf over plain Else, is that we can introduce a new test.  In the above example we use ElseIf to check if the length of the file is less than 1.  To activate the ‘ElseIf’ block, set $File to a non-existent file for example
$File = get-Help about_ifxx.

Note 2: To trigger the final ‘Else’, try changing:
$File = get-Help about_if
to
$File = get-Help about_scope

If you have time, you could add more ‘ElseIf’ statements to cater for other eventualities.  Alternatively, if the ElseIf construction is getting unwieldy, then try the superior switch command.

PowerShell Switch

A curious feature of the construction is that the word ‘Switch’ introduces the input, and is then never seen again, all that you see thereafter is rows of patterns and matching {Statement Blocks}.  Also observe that there is an extra pair of {braces} surrounding the whole pattern section.

The layout below emphasises the branches, or the multiple ‘Patterns’ whose values get switched to their respective {Blocks}.

Switch (pipeline) {

Pattern 1 {Statement block}
Pattern 2 {Statement block}
Pattern n {Statement block}

}

For simple examples, you could write the Switch command all on one line:

Switch (3) { 1{ “Red” } 2{ “Yellow” } 3{ “Green” } }

Result Green.  PowerShell switches the input 3 for Green.

Learning Points

Note 1: Trace the overall structure of the Switch command:
Switch (Value, or Pipeline in parenthesis) {Actions in braces}

Note 2: The “Block” for each Switch is enclosed not only by {braces}, but also by speech marks { “Yellow” }.

Note 3: Remember to pair the initial { brace, with a final matching brace, even if the whole structure spans multiple lines.}

A difficulty occurred when we interrogated the computer’s disks with WMI.  Specifically, the output reports DriveType as a number, whereas we want a meaningful name for the type of disk.  The extra step in this example was to research which drive type corresponded to which number, for example if $Drive.DeviceID returns a value of 3, that means the disk type is a “Hard drive”.

Case Study 1 – Problem with output

# Case Study 1 – Problem
$Disk = get-WmiObject win32_logicaldisk
foreach ($Drive in $Disk) {
$Drive.DeviceID + $Drive.DriveType
}

We want an answer to the question: ‘What does the DriveType number mean?’  It would be useful if the script gave us a name rather than a number.  Research reveals that there are at least 5 possible disk types, therefore multiple ‘If’ statements would be cumbersome, ‘Switch’ is more elegant.

Case Study 2 – Solution with ‘Switch’

# Case Study 2 – Solution with ‘Switch’
$Disk = get-WmiObject win32_logicaldisk
foreach ($Drive in $Disk) {Switch ($Drive.DriveType) {
1{ $Drive.DeviceID + ” Unknown” }
2{ $Drive.DeviceID + ” Floppy” }
3{ $Drive.DeviceID + ” Hard Drive” }
4{ $Drive.DeviceID + ” Network Drive” }
5{ $Drive.DeviceID + ” CD” }
6{ $Drive.DeviceID + ” RAM Disk” }
}
}

Learning Points

Note 1: Before examining the solution in Case Study 2, take the time to understand the underlying WmiObject construction in Case Study 1.  In particular observe the format:
foreach (condition) {Block Command}.

Note 2: The case study solution builds on the first script by adding the Switch block.  To my way of thinking, there are two loops, the outer foreach and an inner Switch loop.  Check what I mean by matching the last two {lonely} braces with their opening counterparts.

Challenges

Challenge 1: Just to get experience and control of the script try changing “Hard Drive” to “Fixed Disk”

Challenge 2: Create a mapped network drive, then run the script again.  Launch Windows Explorer then click on the Tools menu, this is the easiest way to map a local drive letter to a UNC share.

Learning more about PowerShell’s Switch command

When I wanted help about the switch command, at first PowerShell’s help did not do what I wanted.  The secret was to add the about_ prefix.  Try:
help about_switch

What the about_switch help file reveals is that you could use wildcards in the matching clause.

Incidentally, PowerShell supports a whole family of about_ commands, for example you could try:
help about_foreach

Case Study 2 – Featuring Switch with -wildcard

Case Study 2 – Count the types of error message in the Application eventlog

# PowerShell script to count eventlog messages
function EventType{
BEGIN {
$errors = 0
$warnings = 0
$info = 0
}
PROCESS {
switch -wildcard ($_.entrytype) {
“err*” {$errors++}
“warn*” {$warnings++}
“info*” {$info++}
default {}
}#switch block
}#process block
END {
“The Application log contains ” + $errors + ” error messages.”
“The Application log contains ” + $warnings + ” warning messages.”
“The Application log contains ” + $info + ” information messages.”
}#end block
}#function block
get-eventlog “application” -newest 250 | EventType

Note 1: Observe the -wildcard switch with err*, info* and warn*.  To test the effect, try removing the -wildcard parameter.

Summary of PowerShell’s ‘Switch’ command

The ‘If’ family are easy to use for scripts that require branching logic.  However, when the number of options exceeds about 5, then ‘Switch’ is easier to code and easier to add more options.  By trying a few simple examples you will soon appreciate the types of bracket, and the structure of the pattern with its matching statement block.  I say again, ‘Switch’ is one of the most satisfying constructions to create, therefore never miss a chance to replace multiple ‘If’s with one ‘Switch’.

Match and Like

The ‘match’ can be anywhere in the string.  Moreover, the pattern does not have to be a complete match, neither does it have to be at the beginning of the string.  -Match uses regular expressions for pattern matching.  Incidentally -match and the other PowerShell conditional operators all have a negative form, for example -notmatch.

Example 1a – Does not have to be at the beginning

$Guy =”Guy Thomas 1949″
$Guy -match “Th”
Result PS> True

Example 1b – Completely wrong name

$Guy =”Guy Thomas 1949″
$Guy -match “Guido”
Result PS> False

Example 1c – Wrong date

$Guy =”Guy Thomas 1949″
$Guy -match “1948”
Result PS> False

Example 1d – Wildcard ?  Rides to the rescue

$Guy =”Guy Thomas 1949″
$Guy -match “194?”
Result PS> True

Example 1e – Wmiobject and Where

get-wmiobject -list | where {$_.name -match “cim*”}

Negative -notmatch

For negative conditions, there is an alternative form called -notmatch.

With -like, both sides of the expression have to be the same, fortunately, you can employ the usual wildcards * and ?.

Example 2a – Having only part of the string is no good

$Guy =”Guy Thomas 1949″
$Guy -like “Th”
Result PS> False

Example 2b – Just the start of the string not enough

$Guy =”Guy Thomas 1949″
$Guy -like “Guy”
Result PS> False

Example 2c – Wildcard * is useful

$Guy =”Guy Thomas 1949″
$Guy -like “Guy*”
Result PS> True

Example 2d – Wildcard * but the rest has to be correct

$Guy =”Guy Thomas 1949″
$Guy -like “Gzkuy*”
Result PS> False

Example 2e – * Wildcard *  Double wildcards are handy

$Guy =”Guy Thomas 1949″
$Guy -like “*Th*”
Result PS> True

If your logic needs the negative, then try -notlike.  In addition, -notlike and -like have variants that force case sensitivity. -clike and -cnotlike.

Difference Between -like and -match

$Guy =”Guy Thomas 1949″
$Guy -like “Th*”
Result PS> False

$Guy =”Guy Thomas 1949″
$Guy –match “Th*”
Result PS> True

The conditional operator -contains is similar to -eq, except it returns ‘True’ or ‘False’.  -contains is designed for situations where you have a collection and wish to test one particular item.

Example 3a – Checks each item between the commas
$name = “Guy Thomas”, “Alicia Moss”, “Jennifer Jones”
$name -contains “Alicia Moss”
Result PS> True

Example 3b – Needs exact equality
$name = “Guy Thomas”, “Alicia Moss”, “Jennifer Jones”
$name -contains “Jones”
Result PS> False

Example 3c – Wildcards do no good
$name = “Guy Thomas”, “Alicia Moss”, “Jennifer Jones”
$name -contains “*Jones”
Result PS> False

While Loops

The ‘While’ loop is the easiest to master, and also the most flexible.  Each type of PowerShell loop has specific syntax rules; in the case of the ‘While’ loop there are only two elements (condition) and {Block Statement}.  As so often with PowerShell, the type of brackets is highly significant; (Parenthesis for the condition) and {curly braces for the command block}.

The way that the loop works is that PowerShell evaluates the condition at the start of each cycle, and if it’s true, then it executes the command block.

Here is a simple PowerShell ‘while’ loop to calculate, and then display, the 7 times table.

$i =7
while ($i -le 85) { $i; $i +=7}

Learning Points

Note 1: $i is a variable set to 7.  Remember, the mission was to create the seven times table.
Note 2: Observe the two types of bracket (while) {Block Calculation}
Note 3: -le means less than or equals.  (Other comparators are: -eq and -gt)
Note 4: +=7 increments the variable $i by seven on each loop.

Alternatively, we could use a semicolon to join the two statements to form one line.
$i =7;  while ($i -le 85) { $i; $i +=7 }.

Do While Loop

In the ‘Do … While’ loop, PowerShell checks the (condition) at the end of each loop.  One feature of the ‘Do While’ loop is that the {Command Block} is always executed at least once, this is because the ‘While’ comes after the ‘Do’.

$i = 7; do { $i; $i +=7 } while ($i -le 85)

Note 1: Without the semicolon it would need two lines thus:

$i = 7
do { $i; $i +=7 } while ($i -le 85)

Do Until
There is a variation of this style of loop, ‘Do .. Until’.  The layout of the components is the same as ‘Do While’, the only difference is that the logic is changed from, do while condition is true, to, do until condition is true.

$i = 7; do { $i; $i +=7 } until ($i –gt 85)

Foreach Classic PowerShell Loop (3 Examples)

The PowerShell ‘ForEach’ loop is more complex, and has more arguments than the ‘for’ and ‘Do While’.  The key feature is that loop interrogates an array, known as a collection.  In addition to the position, and the type of bracket, observe the tiny, but crucial keyword, ‘in’.

Here is the syntax: ForEach ($item in $array_collection) {command_block}

PowerShell Example 1 – Math

foreach ($number in 1,2,3,4,5,6,7,8,9,10,11,12 ) { $number * 7}

foreach ($number in 1..12 ) { $number * 7}

$NumArray = (1,2,3,4,5,6,7,8,9,10,11,12)
foreach ($number in $numArray ) { $number * 7}

foreach ($number in 1,2,3,4,5,6,7,8,9,10,11,12 ) { $number * 7}

$NumArray = (1..12)
foreach ($number in $numArray ) { $number * 7}

Learning Points

Note 1: By creating five variations, my aim is to give you both perspective and experience of the PowerShell foreach loop.

Note 2: (1..12) is a convenient method of representing a sequence.

PowerShell Example 2 – To display files

Here is an example of a PowerShell ‘foreach’ loop which displays the filename and its size.  In order to get this example to work, create a cmdlet by saving the following into a file, and give it a .ps1 extension.  Call the cmdlet from the PS prompt.  If the file is called ListDoc.ps1, and assuming that the file is in the current directory, then at the PS prompt type:
.\listdoc

Alternatively, from the PS prompt, type the full path D:\scripts\listdoc.

Cmdlet 1

foreach ($file in get-Childitem)
{
$file.name + ” ” +$file.length
}

In Cmdlet 2 (below), we can employ a simple ‘if’ statement to filter .txt files.  Naturally, feel free to alter -eq “.txt” to a more suitable extension.

Cmdlet 2

# PowerShell foreach loop to display files LastAccessTime
“File Name ” + “`t Size” +”`t Last Accessed”
foreach ($file in get-Childitem)
{if ($file.extension -eq “.txt”)
{
$file.name + “`t ” +$file.length + “`t ” +    $file.LastAccessTime
}
}

Learning Points

Note 0: If all else fails, copy the above code, and paste to PowerShell prompt, and then press ‘Enter’.

Note 1: `t means Tab.

Examples:

Replace contents in a text file with other text and write it to a new file:

Get-Content test.txt | ForEach-Object { $_ -replace “foo”, “bar” } | Set-Content test2.txt