Larry_Weiss_PowerShell_Tutorial

advertisement
PowerShell Quick Reference
Chris Morgan – 9/10/2011
Downloading PowerShell -- http://support.microsoft.com/kb/968929
IDEs for PowerShell – ISE comes with it, PowerGUI is a free alternative
Start  Accessories  Windows PowerShell
Set properties on the console window – colors, width, height, buffer, position
Setting prompt
Enter “$profile” at the PowerShell prompt to see where to create the folder
notepad $profile
test-path $profile
Test to see if the file exists
In $profile, create a function like:
function prompt {"PS $pwd>"}
Or
function Prompt {
$max = 40
$str = $pwd.path
if ($str.length -ge $max)
{
$str = "..." + $str.substring($str.length - $max + 4)
}
$history = @(get-history)
$curr = [string]($history.count+1)
$str = $str + "[$curr]"
"PS $str>"
$host.ui.RawUI.WindowTitle = "PS: " + $pwd
}
Three important rules about PowerShell scripts:
1. A PowerShell script has the extension “.ps1”. PowerShell v1.0 and v2.0 both use the same .ps1
extension.
2. To run scripts you have to explicitly enable them by setting the “execution policy”, as follows:
set-executionpolicy remotesigned
3. To run scripts in the current directory just enter the script name. BUT, you have to precede it with “.\”:
.\myscript.ps1
Miscellaneous tips and rules:







All references to variables start with a dollar sign. It says “what follows is a variable name”.
All comparison operators and parameters begin with a dash, as in: –lt -gt -eq -contains –matches
You can save the output of any operation to a variable. For example: $d = dir *.txt
Everything is an object in PowerShell (they all have properties and methods)
Variables don’t have to be declared. They automatically get set to a type. However, you can specify the
type of a variable if you want. $d = [datetime]”06/06/2011” makes the string a datetime variable type
and, hence, $d is too. Other types are [int], [string], [double].
You can find out what properties and methods are defined on an object by using Get-Member, as in
$d | get-member
$profile | get-member
Just typing the name of variable will show you the contents of it
3/17/2016
Document1
Page 1
$profile











Get-help command is your friend. There is lots of built-in help. Try: get-help variables
Get-help has the following 3 options: –examples
-detailed
–full
Get-history command shows a list of recent commands
h command does the same
h 25 gets the 25th command out of the history
h 25 –count 5 gets the 5 commands leading up to and including the 25th command.
<F7> key (like in DOS) pops-up a list of commands you can scroll through.
A comment line in a script begins with a pound sign - #
Comment blocks are <# . . . #>
` (backtick or backquote) is used in scripts to continue a command onto the next line or in a command
to “escape” a character to make it a literal, like in “`#COMMAND” to make the pound sign character a literal
character instead of the beginning of a comment. Also, `t is a tab, `n is a new line, etc. for special
characters.
There is no way to require declaring variables in scripts. It is, however, possible to declare variables
before they are used and to set the scope of the variable (local: (default), private:, script:, global:)
Help
Get-help (or just ‘help’ to display a page at a time) has a list of topics that all start with “about_”. To see all the
topics:
help about_*
get-help profile|out-file profile.txt -encoding ascii|notepad profile.txt
Get-Command to get a list of all the built-in commands
Many normal DOS commands work in PowerShell. However, they may not work in exactly the same way or have
the same options:
dir
md
cd
move copy
cls
ren
(gc is like ‘list’)
Actually, each of these commands is an alias for the real command. To find out what the real command is use
get-alias:
get-alias dir
Or
dir alias:
dir alias:dir
dir alias:d*
to see them all
to see just the alias on dir
to see all commands that start with d that are an alias.
To switch drives, just enter the drive letter, as in DOS. For example: c: or d:
There are other “drives” in PowerShell. Try doing a dir on env:, variable:, or function:
dir env:
dir variable:
dir function:
dir hklm:
dir hkcu:
dir alias:
There are a number of built-in variables (dir variable: to see all variables in memory)
$pid
Process ID of the current process
$pwd
Current path
3/17/2016
Document1
Page 2
$profile
Full path and name of the PowerShell profile file
$home
home path
$pshome
PowerShell path
$psversiontable
PowerShell version info
The dir command can work like you expect:
Gets a list of all the txt files in the current directory
dir *.txt
Variations of the dir (or “Get-ChildItem”) command:
dir
dir
dir
dir
dir
dir
*.txt|sort lastwritetime -desc
| where {$_.PSIsContainer}
| where {!$_.PSIsContainer}
| select name, length
| select {$_.name.padright(20) + "
| select {$_.name.padright(20) + "
Sorts by DateTime in descending order
Gets just a list of directories
Gets just a list of files
Show only the filename and size
" + $_.length} Formats the filename and size some
" + $_.length.tostring().padleft(10)} More formatting
It can also do something you don’t expect – take an array of patterns to search on:
Dir (“*.inc”,”*.pkg”,”*.mac”) Gets all the inc, pkg, and mac files in the current directory.
What is in parentheses is an array of values.
Get the count of directory entries
(dir).count
The parentheses causes the command to execute first
dir.count
This won’t work
If you want to see all the files in subdirectories too, there is a different syntax:
dir * -include *.inc –recurse
Get all the “drives” with the get-psdrive command
get-PSDrive
Change to a “drive” by using the CD command:
cd env:
cd variable:
Then you can use DIR to see all the entries in that drive. The registry can be navigated by using the CD command
to go to a “subdirectory” of the registry “drive”. You can also reference a “subdirectory” by using a “\”, as in:
cd hklm:
dir software\microsoft\office
Scripts


Powershell scripts are text files that have an extension .ps1.
Parameters passed to a script can be accessed by referencing the built-in array

It is a zero-based array. So, the first parameter passed to the script is


$args[]
$args[0]
To run a script called Test.ps1 in powershell, enter at the command prompt:
.\test
parm1
parm2
If you are in the DOS command shell, enter
powershell
3/17/2016
Document1
.\test
first_parm
second_parm
Page 3

You can create a DOS batch file to run a powershell script and retrieve the exit code from the script as
an errorlevel in DOS. Exit the Powershell script with a “exit 10” command. The batch file (call it ps.bat)
runs the script passed on the command line (together with any parameters) and then references the last
exit code from the script:
@echo off
powershell.exe -command “%*” ; exit $LastExitCode
echo Error Code: %errorlevel%
Functions
Function myfunc($parm1, [int]$parm2) {command 1; command2; return $str}
or
Function myfunc {param($parm1, [int]$parm2); command 1; command2; return $str}
Working with Environment Variables
Get the path environment variable and store it in a variable
Display the path with each entry on its own line
Turn the environment string into an array of values.
Display the 6th entry in the path string
Get the number of path entries
Same
Adds an array element to the end
Change the 16th array value to “new stuff”
Changes the last element in the array to “xyz”
Takes the array of elements in the $p1 array and joins them all
together into a single string, with a semi-colon concatenation
character in between each element.
$env:newpath = $p2
Sets the ‘newpath’ environment variable to the $p2 string.
foreach($e in $p1){$e}
Show all the elements in the $p1 array
$env:path += “;c:\dataflex\bin”
Add another path to the environment path variable
$p = $env:path
$p.split(“;”)
$p1 = $p.split(“;”)
$p1[5]
$p1.count
$p1.length
$p1 += “new entry”
$p1[15] = “new stuff”
$p1[($p1.count-1)] = “xyz”
$p2 = $p1 -join (“;”)
String Handling
Now do some more stuff with string handling. Get just the array elements from $p1 where it begins with certain
characters.
foreach($e in $p1){if($e.tolower().startswith(“c:\prog”)){$e}}
By the way, here’s a list of some useful string methods to try out (use get-help to learn more about each):
Clone
PadRight
ToUpper
CompareTo
Remove
Trim
Contains
Replace
TrimEnd
CopyTo
Split
TrimStart
EndsWith
StartsWith
Equals
Substring
GetType
ToCharArray
Insert
ToLower
PadLeft
ToString
File search tutorial
dir *.txt
$txt = dir *.txt
$txt.count
$txt | get-member
foreach ($f in $txt) {$f}
foreach ($f in $txt){$f.name}
$txt | select name
$txt | select –first 5 | select directory, name
$txt | select –last 5 | select directory, name
3/17/2016
Document1
Page 4
dir * -include *.txt –exclude *.flx –recurse
dir * -include *.txt,*.inc,*.pkg –exclude *.flx –recurse
dir
dir
dir
dir
|where
|where
|where
|where
{$_.PSIsContainer}
{!($_.PSIsContainer)}
{$_.length –gt 10000}
{$_.lastwritetime –gt “1/1/2008”}
show only the directories
show all but the directories
show files that are 10k or larger
show files with a date after 1/1/2008
dir –r |select name
recurse all subdirectories
dir -i *.txt –r | select-string “policy”
dir -i *.html -r | select-string "Virtual University"|
select {($_.linenumber.tostring().padright(5) + " " +
$_.line.padright(60).substring(0,60))}
foreach ($f in get-childitem -include *.html -r){$f.name}
foreach ($f in get-childitem -include *.html -r)
{if ($f.creationtime –lt $(get-date).addmonths(-50)){$f.name}}
Double search. This next example looks at all PKG files and gets a list of those that have “procedure entering” in
them. Then it does a second search, but just on this list of files, for those that contain “refresh”:
dir *.pkg|select-string "procedure entering"|select filename -unique|
foreach {dir $_.filename}|select-string "refresh"
dir *.pkg|select-string "procedure entering"|select filename -unique|
foreach {dir $_.filename}|select-string "refresh"|select filename -unique
This line looks at three types of files: PKG, INC, & MAC:
dir ("*.pkg","*.inc","*.mac")|select-string "procedure"|select filename -unique|
foreach {dir $_.filename}|select-string "refresh"|select filename –unique
Files
get-content file.txt
Get the contents of file.txt, splitting the file into lines
gc file.txt
Same
gc fmac –delimiter `#DELIMITER
Get contents of FMAC, but split file at #ENDCOMMAND; not by lines
out-file file.txt –encoding ascii –append
set-content file.txt “Here is some text”
add-content –path file.content –value “here is some text”
clear-content file.txt
(Test-Path file.txt) Test to see if ‘file.txt’ exists.
> file.txt redirect output to a file
>> file.txt redirect that appends output to a file
$fn = [System.IO.Path]::GetTempFileName()
Create a temporary file. We can use it to store info to.
dir *.txt|foreach {move-item $_.fullname .\test} Move all the TXT files from the current dir to subdir “Test”
Some misc examples:
$errlog
$errlog
$errlog
$errlog
$errlog
$errlog
foreach
= get-content c:\windows\temp\errlog.txt
= get-content c:\windows\temp\errlog.txt| measure-object
= get-content c:\windows\temp\errlog.txt -last 10
= get-content c:\windows\temp\errlog.txt -totalcount 100
= get-content c:\windows\temp\errlog.txt -skip 1
= get-content c:\windows\temp\errlog.txt| out-file -encoding ASCII c:\logs\errlog.txt
($line in $errlog) {if($line.contains("getting")){"Found: " + $line.substring(1,17) }}
$errlog| where {$_.contains("getting")} |out-file -encoding ASCII c:\logs\errlog1.txt
3/17/2016
Document1
Page 5
Rename file extension
Dir *.txt | rename-item –newname {$_.name.replace(‘.txt’,’.csv’)}
Get a list of all the file types in the current directory and create a directory for each unique type, but not "INC":
dir |select-object extension |sort-object extension -unique |where {$_.extension -ne ".INC"
|foreach {if (($_.extension -ne "") -and !(test-path $_.extension.substring(1,3)))
{ new-item $_.extension.substring(1,3).ToUpper() -type directory }}
When broken into a 2-step process, this works too:
$a = get-childitem | select-object extension | sort-object extension -unique
foreach ($dir in $a) {if (($dir.extension -ne "") -and !(test-path $dir.extension.substring(1,3)))
{new-item $dir.extension.substring(1,3).ToUpper() -type directory }}
write-host "The number of file types is: " $a.count
Move all TXT and PS1 files to their respective subdirectories
dir ("*.txt","*.ps1")|foreach {$ext = (".\" + $_.extension.substring(1,3)); move-item $_.fullname $ext }
Date handling
$now = get-date
$now | get-member
to see the methods and properties you have access to
$somedate = [DateTime]”01/01/2011”
$now.year
.month
.day
.timeofday
$now.timeofday.hours
.minutes
$now.timeofday.hours.tostring()
$diff = $now - $somedate
$diff.totaldays
$diff is a “TimeSpan” data type, whereas $now is a “DateTime”.
Arrays
$a = 1,2,3,4,5,6,7,8,9,10
$a = 1..10
$min = 10
$max = 18
$a = $min..$max
$a[0] first element
$a.count number of elements
$b = 20, 21, 22, 23, 24
$c = $a + $b
results is 1,2,3,4,5,6,7,8,9,10,20,21,22,23,24,25
Note: See “Working with Environment Variables” above for more on arrays
Sorting and Grouping
$dir = “x:\proj\release”
$phrase = “log”
$f = get-childitem $dir –r –exclude *.zip
$f | select-string $phrase | group-object filename | sort-object count -desc
gc log.txt | group
gc log.txt | sort
gc log.txt | sort –unique
gc log.txt | foreach{$_.trim()} | sort
Remove all the leading spaces on each line before sorting
dir | select extension | sort extension –unique
dir | select extension | group extension | sort count -desc
Get the contents of the set.pkg, trim all the leading spaces, then group all the lines that are alike and sort the
result by number of times each similar line is found in the file and, finally, display the duplicate count and the
text of the line.
3/17/2016
Document1
Page 6
gc set.pkg|foreach{$_.trim()}|group|sort count|foreach {$_.count.tostring() + "
" +$_.name}
For and Foreach
$f = get-content logfile.txt
Get the contents of a text file and move to an array variable
$count = $f.length
for ([int]$i=0 ; $i –lt $count ; $i++) {
if ($f[$i].contains(“some text”)){
$f[$i]
}
}
foreach ($line in $f){ if ($line.contains(“some text”)){$line}}
or
get-content logfile.txt| where {$_.contains(“some test”)}
Processes and Jobs
start-process notepad
Or
$proc = [diagnostics.process]::start("notepad.exe", "$pwd\file.txt")
$proc.close()
Or
$id = $proc.id
stop_process $id
start-sleep –seconds 15
start-process powershell.exe
start-job
stop-job
wait-job
receive-job
get-job
To start up another PowerShell command shell
Start a job in the background while you continue to work
Stop a job you started
Wait until a designated job completes
Get the return result from a running or just completed job
Get a list of current running jobs
CSV and XML files
import-csv
ConvertFrom-csv
export-csv
ConvertTo-csv –delimiter “;”
User Interaction
Write-Host “There are $c files in this directory.”
//where $c=(dir *.txt).count
write-host –nonewline “Press any key to continue...”
write-output “Press any key to continue...”
$key = $host.ui.rawui.readkey(“NoEcho, IncludeKeyDown”)
$input = Read-Host “Enter some text here”
write-host -f white -b red "This is some text"
Display white text on a red background
get-content newfile.txt|foreach {if ($_.contains('second')){write-host -f white -b red $_}
else {write $_} }
Show selected lines as white on red; the others in normal colors
dir *.txt| out-gridview
Word, Excel, and Internet Explorer
$excel = new-object –comobject (“excel.application”)
or
$excel = new-object –comobject excel.application
$wb = $excel.workbooks.add()
3/17/2016
Document1
Page 7
$ws = $wb.worksheets(1)
$excel.visible = $true
$wb.activesheet.cells.item(5,1) = “Hello World”
$ws.cells.item(5,2) = “Another World”
$cell = $wb.activesheet.cells.item(5,1).text
or
$cell = $ws.cells.item(5,2).text
$wb.saveas(“mysheet.xlsx”)
$wb.saveas(“mysheet.csv”,6)
Or, to save as a CSV file.
$wb.close()
$excel.quit()
Option to not display alerts in Excel:
$excel.displayalerts = $false
$wb = $excel.workbooks.open(“mysheet.xlsx”)
$wb.opentext()
$word = new-object –comobject word.application
(more to come here)
$ie = new-object –comobject InternetExplorer.application
$ie.visible = $true
$ie.navigate(http://ingenix.com/login/)
$ie.readystate
$ie.quit()
if ($ie.readystate –eq $null){write-host “IE has been closed”}
if ($ie.readystate –eq 4){write-host “Last request finished”}
Computer Access
Get a list of cookies on the current computer, sorted by date:
$a = new-object –comobject shell.application
$cookies = dir $a.namespace(0x21).self.path | sort lastwritetime –descending
foreach ($cookie in $cookies){$cookie.name}
Or, to get a list of what items are on the desktop, replace “0x21” with “0x0” in line 2.
SQL Server
$sql = new-object system.data.sqlclient.sqlconnection(“Server=HP8430\SQLEXPRESS;
Trusted_Connection=Yes; Database=Northwind”)
$sql.open()
$cmd = $sql.createcommand()
$cmd.commandtext = “select * from customers”
$results = $cmd.ExecuteReader()
while ($results.read()){write-host $results.item(“CompanyName”) “ “ $results.item(“City”)}
$sql.close()
$cmd.commandtext = “create table MyTable(ID int, Name varchar(50), Addr varchar(50), BDay datetime)”
$result = $cmd.ExecuteNonQuery()
$cmd.commandtext = “select count(*) from Customers”
$result = $cmd.ExecuteScalar()
Windows Form
[void][reflection.assembly]::LoadWithPartialName(“System.Windows.Forms”)
$form = new-object Windows.Forms.Form
$button = new-object Windows.Forms.Button
$button.text = “Press here”
$button.dock = “fill”
$button.add_click({form.close()})
$form.controls.add($button)
$form.add_shown({$form.activate()})
$form.showdialog()
3/17/2016
Document1
Page 8
Download