<!--{{{-->
<link rel='alternate' type='application/rss+xml' title='RSS' href='index.xml' />
<!--}}}-->
Background: #fff
Foreground: #000
PrimaryPale: #8cf
PrimaryLight: #18f
PrimaryMid: #04b
PrimaryDark: #014
SecondaryPale: #ffc
SecondaryLight: #fe8
SecondaryMid: #db4
SecondaryDark: #841
TertiaryPale: #eee
TertiaryLight: #ccc
TertiaryMid: #999
TertiaryDark: #666
Error: #f88
/*{{{*/
body {background:[[ColorPalette::Background]]; color:[[ColorPalette::Foreground]];}

a {color:[[ColorPalette::PrimaryMid]];}
a:hover {background-color:[[ColorPalette::PrimaryMid]]; color:[[ColorPalette::Background]];}
a img {border:0;}

h1,h2,h3,h4,h5,h6 {color:[[ColorPalette::SecondaryDark]]; background:transparent;}
h1 {border-bottom:2px solid [[ColorPalette::TertiaryLight]];}
h2,h3 {border-bottom:1px solid [[ColorPalette::TertiaryLight]];}

.button {color:[[ColorPalette::PrimaryDark]]; border:1px solid [[ColorPalette::Background]];}
.button:hover {color:[[ColorPalette::PrimaryDark]]; background:[[ColorPalette::SecondaryLight]]; border-color:[[ColorPalette::SecondaryMid]];}
.button:active {color:[[ColorPalette::Background]]; background:[[ColorPalette::SecondaryMid]]; border:1px solid [[ColorPalette::SecondaryDark]];}

.header {background:[[ColorPalette::PrimaryMid]];}
.headerShadow {color:[[ColorPalette::Foreground]];}
.headerShadow a {font-weight:normal; color:[[ColorPalette::Foreground]];}
.headerForeground {color:[[ColorPalette::Background]];}
.headerForeground a {font-weight:normal; color:[[ColorPalette::PrimaryPale]];}

.tabSelected {color:[[ColorPalette::PrimaryDark]];
	background:[[ColorPalette::TertiaryPale]];
	border-left:1px solid [[ColorPalette::TertiaryLight]];
	border-top:1px solid [[ColorPalette::TertiaryLight]];
	border-right:1px solid [[ColorPalette::TertiaryLight]];
}
.tabUnselected {color:[[ColorPalette::Background]]; background:[[ColorPalette::TertiaryMid]];}
.tabContents {color:[[ColorPalette::PrimaryDark]]; background:[[ColorPalette::TertiaryPale]]; border:1px solid [[ColorPalette::TertiaryLight]];}
.tabContents .button {border:0;}

#sidebar {}
#sidebarOptions input {border:1px solid [[ColorPalette::PrimaryMid]];}
#sidebarOptions .sliderPanel {background:[[ColorPalette::PrimaryPale]];}
#sidebarOptions .sliderPanel a {border:none;color:[[ColorPalette::PrimaryMid]];}
#sidebarOptions .sliderPanel a:hover {color:[[ColorPalette::Background]]; background:[[ColorPalette::PrimaryMid]];}
#sidebarOptions .sliderPanel a:active {color:[[ColorPalette::PrimaryMid]]; background:[[ColorPalette::Background]];}

.wizard {background:[[ColorPalette::PrimaryPale]]; border:1px solid [[ColorPalette::PrimaryMid]];}
.wizard h1 {color:[[ColorPalette::PrimaryDark]]; border:none;}
.wizard h2 {color:[[ColorPalette::Foreground]]; border:none;}
.wizardStep {background:[[ColorPalette::Background]]; color:[[ColorPalette::Foreground]];
	border:1px solid [[ColorPalette::PrimaryMid]];}
.wizardStep.wizardStepDone {background:[[ColorPalette::TertiaryLight]];}
.wizardFooter {background:[[ColorPalette::PrimaryPale]];}
.wizardFooter .status {background:[[ColorPalette::PrimaryDark]]; color:[[ColorPalette::Background]];}
.wizard .button {color:[[ColorPalette::Foreground]]; background:[[ColorPalette::SecondaryLight]]; border: 1px solid;
	border-color:[[ColorPalette::SecondaryPale]] [[ColorPalette::SecondaryDark]] [[ColorPalette::SecondaryDark]] [[ColorPalette::SecondaryPale]];}
.wizard .button:hover {color:[[ColorPalette::Foreground]]; background:[[ColorPalette::Background]];}
.wizard .button:active {color:[[ColorPalette::Background]]; background:[[ColorPalette::Foreground]]; border: 1px solid;
	border-color:[[ColorPalette::PrimaryDark]] [[ColorPalette::PrimaryPale]] [[ColorPalette::PrimaryPale]] [[ColorPalette::PrimaryDark]];}

.wizard .notChanged {background:transparent;}
.wizard .changedLocally {background:#80ff80;}
.wizard .changedServer {background:#8080ff;}
.wizard .changedBoth {background:#ff8080;}
.wizard .notFound {background:#ffff80;}
.wizard .putToServer {background:#ff80ff;}
.wizard .gotFromServer {background:#80ffff;}

#messageArea {border:1px solid [[ColorPalette::SecondaryMid]]; background:[[ColorPalette::SecondaryLight]]; color:[[ColorPalette::Foreground]];}
#messageArea .button {color:[[ColorPalette::PrimaryMid]]; background:[[ColorPalette::SecondaryPale]]; border:none;}

.popupTiddler {background:[[ColorPalette::TertiaryPale]]; border:2px solid [[ColorPalette::TertiaryMid]];}

.popup {background:[[ColorPalette::TertiaryPale]]; color:[[ColorPalette::TertiaryDark]]; border-left:1px solid [[ColorPalette::TertiaryMid]]; border-top:1px solid [[ColorPalette::TertiaryMid]]; border-right:2px solid [[ColorPalette::TertiaryDark]]; border-bottom:2px solid [[ColorPalette::TertiaryDark]];}
.popup hr {color:[[ColorPalette::PrimaryDark]]; background:[[ColorPalette::PrimaryDark]]; border-bottom:1px;}
.popup li.disabled {color:[[ColorPalette::TertiaryMid]];}
.popup li a, .popup li a:visited {color:[[ColorPalette::Foreground]]; border: none;}
.popup li a:hover {background:[[ColorPalette::SecondaryLight]]; color:[[ColorPalette::Foreground]]; border: none;}
.popup li a:active {background:[[ColorPalette::SecondaryPale]]; color:[[ColorPalette::Foreground]]; border: none;}
.popupHighlight {background:[[ColorPalette::Background]]; color:[[ColorPalette::Foreground]];}
.listBreak div {border-bottom:1px solid [[ColorPalette::TertiaryDark]];}

.tiddler .defaultCommand {font-weight:bold;}

.shadow .title {color:[[ColorPalette::TertiaryDark]];}

.title {color:[[ColorPalette::SecondaryDark]];}
.subtitle {color:[[ColorPalette::TertiaryDark]];}

.toolbar {color:[[ColorPalette::PrimaryMid]];}
.toolbar a {color:[[ColorPalette::TertiaryLight]];}
.selected .toolbar a {color:[[ColorPalette::TertiaryMid]];}
.selected .toolbar a:hover {color:[[ColorPalette::Foreground]];}

.tagging, .tagged {border:1px solid [[ColorPalette::TertiaryPale]]; background-color:[[ColorPalette::TertiaryPale]];}
.selected .tagging, .selected .tagged {background-color:[[ColorPalette::TertiaryLight]]; border:1px solid [[ColorPalette::TertiaryMid]];}
.tagging .listTitle, .tagged .listTitle {color:[[ColorPalette::PrimaryDark]];}
.tagging .button, .tagged .button {border:none;}

.footer {color:[[ColorPalette::TertiaryLight]];}
.selected .footer {color:[[ColorPalette::TertiaryMid]];}

.error, .errorButton {color:[[ColorPalette::Foreground]]; background:[[ColorPalette::Error]];}
.warning {color:[[ColorPalette::Foreground]]; background:[[ColorPalette::SecondaryPale]];}
.lowlight {background:[[ColorPalette::TertiaryLight]];}

.zoomer {background:none; color:[[ColorPalette::TertiaryMid]]; border:3px solid [[ColorPalette::TertiaryMid]];}

.imageLink, #displayArea .imageLink {background:transparent;}

.annotation {background:[[ColorPalette::SecondaryLight]]; color:[[ColorPalette::Foreground]]; border:2px solid [[ColorPalette::SecondaryMid]];}

.viewer .listTitle {list-style-type:none; margin-left:-2em;}
.viewer .button {border:1px solid [[ColorPalette::SecondaryMid]];}
.viewer blockquote {border-left:3px solid [[ColorPalette::TertiaryDark]];}

.viewer table, table.twtable {border:2px solid [[ColorPalette::TertiaryDark]];}
.viewer th, .viewer thead td, .twtable th, .twtable thead td {background:[[ColorPalette::SecondaryMid]]; border:1px solid [[ColorPalette::TertiaryDark]]; color:[[ColorPalette::Background]];}
.viewer td, .viewer tr, .twtable td, .twtable tr {border:1px solid [[ColorPalette::TertiaryDark]];}

.viewer pre {border:1px solid [[ColorPalette::SecondaryLight]]; background:[[ColorPalette::SecondaryPale]];}
.viewer code {color:[[ColorPalette::SecondaryDark]];}
.viewer hr {border:0; border-top:dashed 1px [[ColorPalette::TertiaryDark]]; color:[[ColorPalette::TertiaryDark]];}

.highlight, .marked {background:[[ColorPalette::SecondaryLight]];}

.editor input {border:1px solid [[ColorPalette::PrimaryMid]];}
.editor textarea {border:1px solid [[ColorPalette::PrimaryMid]]; width:100%;}
.editorFooter {color:[[ColorPalette::TertiaryMid]];}
.readOnly {background:[[ColorPalette::TertiaryPale]];}

#backstageArea {background:[[ColorPalette::Foreground]]; color:[[ColorPalette::TertiaryMid]];}
#backstageArea a {background:[[ColorPalette::Foreground]]; color:[[ColorPalette::Background]]; border:none;}
#backstageArea a:hover {background:[[ColorPalette::SecondaryLight]]; color:[[ColorPalette::Foreground]]; }
#backstageArea a.backstageSelTab {background:[[ColorPalette::Background]]; color:[[ColorPalette::Foreground]];}
#backstageButton a {background:none; color:[[ColorPalette::Background]]; border:none;}
#backstageButton a:hover {background:[[ColorPalette::Foreground]]; color:[[ColorPalette::Background]]; border:none;}
#backstagePanel {background:[[ColorPalette::Background]]; border-color: [[ColorPalette::Background]] [[ColorPalette::TertiaryDark]] [[ColorPalette::TertiaryDark]] [[ColorPalette::TertiaryDark]];}
.backstagePanelFooter .button {border:none; color:[[ColorPalette::Background]];}
.backstagePanelFooter .button:hover {color:[[ColorPalette::Foreground]];}
#backstageCloak {background:[[ColorPalette::Foreground]]; opacity:0.6; filter:alpha(opacity=60);}
/*}}}*/
/*{{{*/
* html .tiddler {height:1%;}

body {font-size:.75em; font-family:arial,helvetica; margin:0; padding:0;}

h1,h2,h3,h4,h5,h6 {font-weight:bold; text-decoration:none;}
h1,h2,h3 {padding-bottom:1px; margin-top:1.2em;margin-bottom:0.3em;}
h4,h5,h6 {margin-top:1em;}
h1 {font-size:1.35em;}
h2 {font-size:1.25em;}
h3 {font-size:1.1em;}
h4 {font-size:1em;}
h5 {font-size:.9em;}

hr {height:1px;}

a {text-decoration:none;}

dt {font-weight:bold;}

ol {list-style-type:decimal;}
ol ol {list-style-type:lower-alpha;}
ol ol ol {list-style-type:lower-roman;}
ol ol ol ol {list-style-type:decimal;}
ol ol ol ol ol {list-style-type:lower-alpha;}
ol ol ol ol ol ol {list-style-type:lower-roman;}
ol ol ol ol ol ol ol {list-style-type:decimal;}

.txtOptionInput {width:11em;}

#contentWrapper .chkOptionInput {border:0;}

.externalLink {text-decoration:underline;}

.indent {margin-left:3em;}
.outdent {margin-left:3em; text-indent:-3em;}
code.escaped {white-space:nowrap;}

.tiddlyLinkExisting {font-weight:bold;}
.tiddlyLinkNonExisting {font-style:italic;}

/* the 'a' is required for IE, otherwise it renders the whole tiddler in bold */
a.tiddlyLinkNonExisting.shadow {font-weight:bold;}

#mainMenu .tiddlyLinkExisting,
	#mainMenu .tiddlyLinkNonExisting,
	#sidebarTabs .tiddlyLinkNonExisting {font-weight:normal; font-style:normal;}
#sidebarTabs .tiddlyLinkExisting {font-weight:bold; font-style:normal;}

.header {position:relative;}
.header a:hover {background:transparent;}
.headerShadow {position:relative; padding:4.5em 0 1em 1em; left:-1px; top:-1px;}
.headerForeground {position:absolute; padding:4.5em 0 1em 1em; left:0; top:0;}

.siteTitle {font-size:3em;}
.siteSubtitle {font-size:1.2em;}

#mainMenu {position:absolute; left:0; width:10em; text-align:right; line-height:1.6em; padding:1.5em 0.5em 0.5em 0.5em; font-size:1.1em;}

#sidebar {position:absolute; right:3px; width:16em; font-size:.9em;}
#sidebarOptions {padding-top:0.3em;}
#sidebarOptions a {margin:0 0.2em; padding:0.2em 0.3em; display:block;}
#sidebarOptions input {margin:0.4em 0.5em;}
#sidebarOptions .sliderPanel {margin-left:1em; padding:0.5em; font-size:.85em;}
#sidebarOptions .sliderPanel a {font-weight:bold; display:inline; padding:0;}
#sidebarOptions .sliderPanel input {margin:0 0 0.3em 0;}
#sidebarTabs .tabContents {width:15em; overflow:hidden;}

.wizard {padding:0.1em 1em 0 2em;}
.wizard h1 {font-size:2em; font-weight:bold; background:none; padding:0; margin:0.4em 0 0.2em;}
.wizard h2 {font-size:1.2em; font-weight:bold; background:none; padding:0; margin:0.4em 0 0.2em;}
.wizardStep {padding:1em 1em 1em 1em;}
.wizard .button {margin:0.5em 0 0; font-size:1.2em;}
.wizardFooter {padding:0.8em 0.4em 0.8em 0;}
.wizardFooter .status {padding:0 0.4em; margin-left:1em;}
.wizard .button {padding:0.1em 0.2em;}

#messageArea {position:fixed; top:2em; right:0; margin:0.5em; padding:0.5em; z-index:2000; _position:absolute;}
.messageToolbar {display:block; text-align:right; padding:0.2em;}
#messageArea a {text-decoration:underline;}

.tiddlerPopupButton {padding:0.2em;}
.popupTiddler {position: absolute; z-index:300; padding:1em; margin:0;}

.popup {position:absolute; z-index:300; font-size:.9em; padding:0; list-style:none; margin:0;}
.popup .popupMessage {padding:0.4em;}
.popup hr {display:block; height:1px; width:auto; padding:0; margin:0.2em 0;}
.popup li.disabled {padding:0.4em;}
.popup li a {display:block; padding:0.4em; font-weight:normal; cursor:pointer;}
.listBreak {font-size:1px; line-height:1px;}
.listBreak div {margin:2px 0;}

.tabset {padding:1em 0 0 0.5em;}
.tab {margin:0 0 0 0.25em; padding:2px;}
.tabContents {padding:0.5em;}
.tabContents ul, .tabContents ol {margin:0; padding:0;}
.txtMainTab .tabContents li {list-style:none;}
.tabContents li.listLink { margin-left:.75em;}

#contentWrapper {display:block;}
#splashScreen {display:none;}

#displayArea {margin:1em 17em 0 14em;}

.toolbar {text-align:right; font-size:.9em;}

.tiddler {padding:1em 1em 0;}

.missing .viewer,.missing .title {font-style:italic;}

.title {font-size:1.6em; font-weight:bold;}

.missing .subtitle {display:none;}
.subtitle {font-size:1.1em;}

.tiddler .button {padding:0.2em 0.4em;}

.tagging {margin:0.5em 0.5em 0.5em 0; float:left; display:none;}
.isTag .tagging {display:block;}
.tagged {margin:0.5em; float:right;}
.tagging, .tagged {font-size:0.9em; padding:0.25em;}
.tagging ul, .tagged ul {list-style:none; margin:0.25em; padding:0;}
.tagClear {clear:both;}

.footer {font-size:.9em;}
.footer li {display:inline;}

.annotation {padding:0.5em; margin:0.5em;}

* html .viewer pre {width:99%; padding:0 0 1em 0;}
.viewer {line-height:1.4em; padding-top:0.5em;}
.viewer .button {margin:0 0.25em; padding:0 0.25em;}
.viewer blockquote {line-height:1.5em; padding-left:0.8em;margin-left:2.5em;}
.viewer ul, .viewer ol {margin-left:0.5em; padding-left:1.5em;}

.viewer table, table.twtable {border-collapse:collapse; margin:0.8em 1.0em;}
.viewer th, .viewer td, .viewer tr,.viewer caption,.twtable th, .twtable td, .twtable tr,.twtable caption {padding:3px;}
table.listView {font-size:0.85em; margin:0.8em 1.0em;}
table.listView th, table.listView td, table.listView tr {padding:0 3px 0 3px;}

.viewer pre {padding:0.5em; margin-left:0.5em; font-size:1.2em; line-height:1.4em; overflow:auto;}
.viewer code {font-size:1.2em; line-height:1.4em;}

.editor {font-size:1.1em;}
.editor input, .editor textarea {display:block; width:100%; font:inherit;}
.editorFooter {padding:0.25em 0; font-size:.9em;}
.editorFooter .button {padding-top:0; padding-bottom:0;}

.fieldsetFix {border:0; padding:0; margin:1px 0px;}

.zoomer {font-size:1.1em; position:absolute; overflow:hidden;}
.zoomer div {padding:1em;}

* html #backstage {width:99%;}
* html #backstageArea {width:99%;}
#backstageArea {display:none; position:relative; overflow: hidden; z-index:150; padding:0.3em 0.5em;}
#backstageToolbar {position:relative;}
#backstageArea a {font-weight:bold; margin-left:0.5em; padding:0.3em 0.5em;}
#backstageButton {display:none; position:absolute; z-index:175; top:0; right:0;}
#backstageButton a {padding:0.1em 0.4em; margin:0.1em;}
#backstage {position:relative; width:100%; z-index:50;}
#backstagePanel {display:none; z-index:100; position:absolute; width:90%; margin-left:3em; padding:1em;}
.backstagePanelFooter {padding-top:0.2em; float:right;}
.backstagePanelFooter a {padding:0.2em 0.4em;}
#backstageCloak {display:none; z-index:20; position:absolute; width:100%; height:100px;}

.whenBackstage {display:none;}
.backstageVisible .whenBackstage {display:block;}
/*}}}*/
/***
StyleSheet for use when a translation requires any css style changes.
This StyleSheet can be used directly by languages such as Chinese, Japanese and Korean which need larger font sizes.
***/
/*{{{*/
body {font-size:0.8em;}
#sidebarOptions {font-size:1.05em;}
#sidebarOptions a {font-style:normal;}
#sidebarOptions .sliderPanel {font-size:0.95em;}
.subtitle {font-size:0.8em;}
.viewer table.listView {font-size:0.95em;}
/*}}}*/
/*{{{*/
@media print {
#mainMenu, #sidebar, #messageArea, .toolbar, #backstageButton, #backstageArea {display: none !important;}
#displayArea {margin: 1em 1em 0em;}
noscript {display:none;} /* Fixes a feature in Firefox 1.5.0.2 where print preview displays the noscript content */
}
/*}}}*/
<!--{{{-->
<div class='header' macro='gradient vert [[ColorPalette::PrimaryLight]] [[ColorPalette::PrimaryMid]]'>
<div class='headerShadow'>
<span class='siteTitle' refresh='content' tiddler='SiteTitle'></span>&nbsp;
<span class='siteSubtitle' refresh='content' tiddler='SiteSubtitle'></span>
</div>
<div class='headerForeground'>
<span class='siteTitle' refresh='content' tiddler='SiteTitle'></span>&nbsp;
<span class='siteSubtitle' refresh='content' tiddler='SiteSubtitle'></span>
</div>
</div>
<div id='mainMenu' refresh='content' tiddler='MainMenu'></div>
<div id='sidebar'>
<div id='sidebarOptions' refresh='content' tiddler='SideBarOptions'></div>
<div id='sidebarTabs' refresh='content' force='true' tiddler='SideBarTabs'></div>
</div>
<div id='displayArea'>
<div id='messageArea'></div>
<div id='tiddlerDisplay'></div>
</div>
<!--}}}-->
<!--{{{-->
<div class='toolbar' macro='toolbar [[ToolbarCommands::ViewToolbar]]'></div>
<div class='title' macro='view title'></div>
<div class='subtitle'><span macro='view modifier link'></span>, <span macro='view modified date'></span> (<span macro='message views.wikified.createdPrompt'></span> <span macro='view created date'></span>)</div>
<div class='tagging' macro='tagging'></div>
<div class='tagged' macro='tags'></div>
<div class='viewer' macro='view text wikified'></div>
<div class='tagClear'></div>
<!--}}}-->
<!--{{{-->
<div class='toolbar' macro='toolbar [[ToolbarCommands::EditToolbar]]'></div>
<div class='title' macro='view title'></div>
<div class='editor' macro='edit title'></div>
<div macro='annotations'></div>
<div class='editor' macro='edit text'></div>
<div class='editor' macro='edit tags'></div><div class='editorFooter'><span macro='message views.editor.tagPrompt'></span><span macro='tagChooser excludeLists'></span></div>
<!--}}}-->
To get started with this blank [[TiddlyWiki]], you'll need to modify the following tiddlers:
* [[SiteTitle]] & [[SiteSubtitle]]: The title and subtitle of the site, as shown above (after saving, they will also appear in the browser title bar)
* [[MainMenu]]: The menu (usually on the left)
* [[DefaultTiddlers]]: Contains the names of the tiddlers that you want to appear when the TiddlyWiki is opened
You'll also need to enter your username for signing your edits: <<option txtUserName>>
These [[InterfaceOptions]] for customising [[TiddlyWiki]] are saved in your browser

Your username for signing your edits. Write it as a [[WikiWord]] (eg [[JoeBloggs]])

<<option txtUserName>>
<<option chkSaveBackups>> [[SaveBackups]]
<<option chkAutoSave>> [[AutoSave]]
<<option chkRegExpSearch>> [[RegExpSearch]]
<<option chkCaseSensitiveSearch>> [[CaseSensitiveSearch]]
<<option chkAnimate>> [[EnableAnimations]]

----
Also see [[AdvancedOptions]]
<<importTiddlers>>
PS C:\WINDOWS\system32> Get-ADUser -Filter * -SearchBase "DC=SHAN,DC=LOCAL"

{{{
DistinguishedName : CN=Administrator,CN=Users,DC=shan,DC=local
Enabled           : True
GivenName         :
Name              : Administrator
ObjectClass       : user
ObjectGUID        : 0350c62d-8f53-4911-bf14-e05fa5d4a304
SamAccountName    : Administrator
SID               : S-1-5-21-3943950521-2127120831-1704551434-500
Surname           :
UserPrincipalName :

DistinguishedName : CN=Guest,CN=Users,DC=shan,DC=local
Enabled           : False
GivenName         :
Name              : Guest
ObjectClass       : user
ObjectGUID        : ea2bcfc3-7496-407d-9677-824560511d95
SamAccountName    : Guest
SID               : S-1-5-21-3943950521-2127120831-1704551434-501
Surname           :
UserPrincipalName :

DistinguishedName : CN=krbtgt,CN=Users,DC=shan,DC=local
Enabled           : False
GivenName         :
Name              : krbtgt
ObjectClass       : user
ObjectGUID        : 7b2d178e-c8b5-48d9-9a23-1b0e9ba951f5
SamAccountName    : krbtgt
SID               : S-1-5-21-3943950521-2127120831-1704551434-502
Surname           :
UserPrincipalName :

DistinguishedName : CN=Glen John,CN=Users,DC=shan,DC=local
Enabled           : True
GivenName         : Glen
Name              : Glen John
ObjectClass       : user
ObjectGUID        : 704e48bd-0901-4b01-9805-ef874fa141a5
SamAccountName    : GlenJohn
SID               : S-1-5-21-3943950521-2127120831-1704551434-1113
Surname           : John
UserPrincipalName : GlenJohn@shan.local



PS C:\WINDOWS\system32>

}}}
PS C:\WINDOWS\system32> Get-ADUser -Filter * -SearchBase "CN=administrator,CN=Users,DC=shan,DC=local"

{{{
DistinguishedName : CN=Administrator,CN=Users,DC=shan,DC=local
Enabled           : True
GivenName         :
Name              : Administrator
ObjectClass       : user
ObjectGUID        : 0350c62d-8f53-4911-bf14-e05fa5d4a304
SamAccountName    : Administrator
SID               : S-1-5-21-3943950521-2127120831-1704551434-500
Surname           :
UserPrincipalName :
}}}
http://miromannino.com/exitwindowsex-in-c/
http://kidvn-lab.googlecode.com/svn/branches/tools/PCAssistant1/PCAssistant/PowerOff.cs
http://csharpdocument.blogspot.com.au/2013/11/how-to-lock-log-off-restart-shutdown.html
http://midnightprogrammer.net/post/ShoutdownLogoffHibernateStand-By-Use-CODE-to-do-em-all/
http://dilipkakadiya.blogspot.com.au/2011/11/how-can-lock-logoff-reboot-shutdown.html
http://stackoverflow.hewgill.com/questions/142/911/1.html
http://blogs.technet.com/b/heyscriptingguy/archive/2010/06/10/hey-scripting-guy-how-can-i-log-out-a-user-if-they-launch-a-particular-application.aspx
!Rename the computer
{{{
netdom renamecomputer CoreD /rename InCoreD    (CoreD - OldName, InCoreD - NewName)
}}}
!Show all the ipv4 interfaces using netsh
{{{
Netsh int ipv4 sh int
}}}
http://www.123greetings.com/createcard?315993
powershell /ps/Set-DisplayOff.ps1
[[Understanding the Windows Server Failover Cluster Quorum in Windows Server 2012 R2|http://blogs.msdn.com/b/microsoft_press/archive/2014/04/28/from-the-mvps-understanding-the-windows-server-failover-cluster-quorum-in-windows-server-2012-r2.aspx]]
[HQEDC.shan.local]: PS C:\> Get-Partition

{{{
   Disk Number: 0

PartitionNumber  DriveLetter Offset                                        Size Type
---------------  ----------- ------                                        ---- ----
1                            1048576                                     300 MB Recovery
2                            315621376                                    99 MB System
3                            419430400                                   128 MB Reserved
4                C           553648128                                 29.48 GB Basic
}}}
[HQEDC.shan.local]: PS C:\> Get-Partition |ft -auto

{{{
   Disk Number: 0

PartitionNumber DriveLetter Offset        Size Type
--------------- ----------- ------        ---- ----
1                           1048576     300 MB Recovery
2                           315621376    99 MB System
3                           419430400   128 MB Reserved
4               C           553648128 29.48 GB Basic
}}}
[HQEDC.shan.local]: PS C:\> Get-Volume
{{{
DriveLetter       FileSystemLabel  FileSystem       DriveType        HealthStatus        SizeRemaining             Size
-----------       ---------------  ----------       ---------        ------------        -------------             ----
C                                  NTFS             Fixed            Healthy                  20.35 GB         29.48 GB
                  Recovery         NTFS             Fixed            Healthy                  56.59 MB           300 MB
D                 IR3_SSS_X64FR... UDF              CD-ROM           Healthy                       0 B          4.23 GB
}}}
{{{
[HQEDC.shan.local]: PS C:\> Get-Volume |ft -auto

DriveLetter FileSystemLabel           FileSystem DriveType HealthStatus SizeRemaining     Size
----------- ---------------           ---------- --------- ------------ -------------     ----
C                                     NTFS       Fixed     Healthy           20.35 GB 29.48 GB
            Recovery                  NTFS       Fixed     Healthy           56.59 MB   300 MB
D           IR3_SSS_X64FREE_EN-US_DV9 UDF        CD-ROM    Healthy                0 B  4.23 GB
}}}
[HQEDC.shan.local]: PS C:\> Get-Volume –DriveLetter C,D | ft -auto
{{{
DriveLetter FileSystemLabel           FileSystem DriveType HealthStatus SizeRemaining     Size
----------- ---------------           ---------- --------- ------------ -------------     ----
C                                     NTFS       Fixed     Healthy           20.35 GB 29.48 GB
D           IR3_SSS_X64FREE_EN-US_DV9 UDF        CD-ROM    Healthy                0 B  4.23 GB
}}}
[HQEDC.shan.local]: PS C:\> Get-Volume –DriveLetter C,D | ft -auto
{{{
DriveLetter FileSystemLabel           FileSystem DriveType HealthStatus SizeRemaining     Size
----------- ---------------           ---------- --------- ------------ -------------     ----
C                                     NTFS       Fixed     Healthy           20.35 GB 29.48 GB
D           IR3_SSS_X64FREE_EN-US_DV9 UDF        CD-ROM    Healthy                0 B  4.23 GB
}}}
[[Changing the Hyper-V Server login experience|http://blogs.msdn.com/b/virtual_pc_guy/archive/2013/03/13/changing-the-hyper-v-server-login-experience.aspx]]
[[powershell.com|http://powershell.com/cs/]]
[[10 Awesome Hyper-V Cmdlets|http://www.altaro.com/hyper-v/10-awesome-hyper-v-cmdlets/]]
[[Essential PowerShell Cmdlets for Auditing and Maintaining Storage|http://www.tomsitpro.com/articles/powershell-for-storage,2-764.html]]
[[The Best Cmdlets for PowerShellhttp://www.admin-ma|gazine.com/Articles/Top-PowerShell-Cmdlets]]
http://stackoverflow.com/questions/10241816/powershell-send-mailmessage-email-to-multiple-recipients
https://4sysops.com/archives/send-mailmessage-paramaters-and-examples/
http://poshcode.org/?list=10&page=4
https://blog.netspi.com/15-ways-to-bypass-the-powershell-execution-policy/
http://pubs.vmware.com/vCAC-60/index.jsp?topic=%2Fcom.vmware.vcac.iaas.all.doc%2FGUID-C86DCF49-F23B-4B9C-9FD5-95524FB74F01.html
/***
|''Name:''|LoadRemoteFileThroughProxy (previous LoadRemoteFileHijack)|
|''Description:''|When the TiddlyWiki file is located on the web (view over http) the content of [[SiteProxy]] tiddler is added in front of the file url. If [[SiteProxy]] does not exist "/proxy/" is added. |
|''Version:''|1.1.0|
|''Date:''|mar 17, 2007|
|''Source:''|http://tiddlywiki.bidix.info/#LoadRemoteFileHijack|
|''Author:''|BidiX (BidiX (at) bidix (dot) info)|
|''License:''|[[BSD open source license|http://tiddlywiki.bidix.info/#%5B%5BBSD%20open%20source%20license%5D%5D ]]|
|''~CoreVersion:''|2.2.0|
***/
//{{{
version.extensions.LoadRemoteFileThroughProxy = {
 major: 1, minor: 1, revision: 0, 
 date: new Date("mar 17, 2007"), 
 source: "http://tiddlywiki.bidix.info/#LoadRemoteFileThroughProxy"};

if (!window.bidix) window.bidix = {}; // bidix namespace
if (!bidix.core) bidix.core = {};

bidix.core.loadRemoteFile = loadRemoteFile;
loadRemoteFile = function(url,callback,params)
{
 if ((document.location.toString().substr(0,4) == "http") && (url.substr(0,4) == "http")){ 
 url = store.getTiddlerText("SiteProxy", "/proxy/") + url;
 }
 return bidix.core.loadRemoteFile(url,callback,params);
}
//}}}
!Create a single new user account
{{{
[HQEDC.shan.local]: PS C:\Users\Administrator\Documents> New-ADUser -Name "Phil Gibbins" -GivenName Phil -Surname Gibbin
s -SamAccountName pgibbins -UserPrincipalName pgibbins@shan.local
}}}
[HQEDC.shan.local]: PS C:\Users\Administrator\Documents>  Get-ADUser pgibbins

{{{
DistinguishedName : CN=Phil Gibbins,CN=Users,DC=shan,DC=local
Enabled           : False
GivenName         : Phil
Name              : Phil Gibbins
ObjectClass       : user
ObjectGUID        : b01c7f72-ba35-4e8f-b7cd-3069e230d86f
SamAccountName    : pgibbins
SID               : S-1-5-21-3943950521-2127120831-1704551434-1114
Surname           : Gibbins
UserPrincipalName : pgibbins@shan.local
}}}
! Create a new user account and specify a password
{{{
[HQEDC.shan.local]: PS C:\Users\Administrator\Documents> New-ADUser -Name "Sam Guna" -GivenName Sam -Surname Guna -SamA
countName sguna -UserPrincipalName sguna@shan.local -AccountPassword (Read-Host -AsSecureString "AccountPassword")
WARNING: A script or application on the remote computer HQEDC.SHAN.LOCAL is sending a prompt request. When you are
prompted, enter sensitive information, such as credentials or passwords, only if you trust the remote computer and the
application or script that is requesting the data.
AccountPassword: ********
[HQEDC.shan.local]: PS C:\Users\Administrator\Documents>  Get-ADUser sguna


DistinguishedName : CN=Sam Guna,CN=Users,DC=shan,DC=local
Enabled           : False
GivenName         : Sam
Name              : Sam Guna
ObjectClass       : user
ObjectGUID        : 4e1f578f-d4e6-44d4-b166-a198a7b0ff48
SamAccountName    : sguna
SID               : S-1-5-21-3943950521-2127120831-1704551434-1115
Surname           : Guna
UserPrincipalName : sguna@shan.local
}}}
!Create and enable a new user account
{{{

[HQEDC.shan.local]: PS C:\Users\Administrator\Documents> New-ADUser -Name "Alice Rajah" -GivenName Alice -Surname Rajah
-SamAccountName arajah -UserPrincipalName arajah@shan.local -AccountPassword (Read-Host -AsSecureString "AccountPassword
") -PassThru | Enable-ADAccount
WARNING: A script or application on the remote computer HQEDC.SHAN.LOCAL is sending a prompt request. When you are
prompted, enter sensitive information, such as credentials or passwords, only if you trust the remote computer and the
application or script that is requesting the data.
AccountPassword: ********
[HQEDC.shan.local]: PS C:\Users\Administrator\Documents>  Get-ADUser arajah


DistinguishedName : CN=Alice Rajah,CN=Users,DC=shan,DC=local
Enabled           : True
GivenName         : Alice
Name              : Alice Rajah
ObjectClass       : user
ObjectGUID        : 45643510-b843-4fb1-be00-9796e1320749
SamAccountName    : arajah
SID               : S-1-5-21-3943950521-2127120831-1704551434-1116
Surname           : Rajah
UserPrincipalName : arajah@shan.local



[HQEDC.shan.local]: PS C:\Users\Administrator\Documents>

}}}
Ref: http://www.windowsnetworking.com/articles-tutorials/windows-server-2012/creating-active-directory-accounts-using-powershell.html
https://www.sapien.com/blog/2012/05/16/powershell-studio-creating-responsive-forms/
https://community.spiceworks.com/topic/757434-can-i-write-html-anything-to-ping-a-host-name-and-return-a-color
{{{
Ref: http://stackoverflow.com/questions/28045009/checking-uptime-of-remote-server-in-powershell
$wmi = Get-WMIObject -Class Win32_OperatingSystem
$lastboottime = $wmi.ConvertToDateTime($wmi.LastBootUpTime)
$sysuptime = (Get-Date) - $lastboottime
$uptime = "   UPTIME           :    $($sysuptime.days) Days, $($sysuptime.hours) Hours, $($sysuptime.minutes) Minutes, $($sysuptime.seconds) Seconds"
}}}
eg:
{{{
$wmi = Get-WMIObject -Class Win32_OperatingSystem
$lastboottime = $wmi.ConvertToDateTime($wmi.LastBootUpTime)
$sysuptime = (Get-Date) - $lastboottime
$uptime = "   UPTIME           :    $($sysuptime.days) Days, $($sysuptime.hours) Hours, $($sysuptime.minutes) Minutes, $($sysuptime.seconds) Seconds"
PS C:\Users\Sara> $uptime
   UPTIME           :    2 Days, 1 Hours, 49 Minutes, 6 Seconds
PS C:\Users\Sara>
}}}
{{{
Ref:  http://blogs.msdn.com/b/powershell/archive/2009/08/12/get-systemuptime-and-working-with-the-wmi-date-format.aspx
function Get-SystemUptime            
{            
    $operatingSystem = Get-WmiObject Win32_OperatingSystem                
    [Management.ManagementDateTimeConverter]::ToDateTime($operatingSystem.LastBootUpTime)            
}
}}}
eg:
{{{
PS C:\Users\Sara> function Get-SystemUptime
>> {
>>     $operatingSystem = Get-WmiObject Win32_OperatingSystem
>>     [Management.ManagementDateTimeConverter]::ToDateTime($operatingSystem.LastBootUpTime)
>> }
PS C:\Users\Sara> Get-SystemUptime

Saturday, 30 January 2016 8:03:00 AM
}}}

{{{
Ref: http://www.experts-exchange.com/questions/28309768/Powershell-help.html
$computer = read-host "Please type in computer name you would like to check uptime on"

$lastboottime = (Get-WmiObject -Class Win32_OperatingSystem -computername $computer).LastBootUpTime

$sysuptime = (Get-Date) – [System.Management.ManagementDateTimeconverter]::ToDateTime($lastboottime) 
  
Write-Host "$computer has been up for: " $sysuptime.days "days" $sysuptime.hours "hours" $sysuptime.minutes "minutes" $sysuptime.seconds "seconds"
}}}
{{{
ref: https://github.com/preflightsiren/Sysadmin-Scripts/blob/master/Get-Uptime.ps1
function Get-Uptime {
param($computer = "localhost")

	$lastboottime = (Get-WmiObject -Class Win32_OperatingSystem -computername $computer).LastBootUpTime
	$sysuptime = (Get-Date) – [System.Management.ManagementDateTimeconverter]::ToDateTime($lastboottime)
	Write-Host "System($computer) has an Uptime of: " $sysuptime.days "days" $sysuptime.hours `
	"hours" $sysuptime.minutes "minutes" $sysuptime.seconds "seconds"

}
}}}
eg:
{{{

PS C:\Users\Sara> function Get-Uptime {
>> param($computer = "localhost")
>>
>> $lastboottime = (Get-WmiObject -Class Win32_OperatingSystem -computername $computer).LastBootUpTime
>> $sysuptime = (Get-Date) – [System.Management.ManagementDateTimeconverter]::ToDateTime($lastboottime)
>> Write-Host "System($computer) has an Uptime of: " $sysuptime.days "days" $sysuptime.hours `
>> "hours" $sysuptime.minutes "minutes" $sysuptime.seconds "seconds"
>>
>> }
PS C:\Users\Sara> Get-Uptime
System(localhost) has an Uptime of:  2 days 2 hours 21 minutes 16 seconds
PS C:\Users\Sara>
}}}
https://www.reddit.com/r/PowerShell/search?q=flair%3ASolved&sort=new&restrict_sr=on  <==solved
https://eaglebcr.wordpress.com/category/microsoft/batch-scripting/
http://bytestipsscripts.blogspot.com.au/




http://itblog.roheve.nl/2014/09/using-net-to-convert-wmi-datetime-to.html
Ref: https://rkeithhill.wordpress.com/2013/05/08/using-powershell-to-analyze-your-pcs-sleep-wake-behavior/
{{{
param($Newest = 50)

function Parse-EventLogEntry
{
    param(
        [Parameter(Mandatory=$true, Position=0, ValueFromPipeline=$true)]
        [System.Diagnostics.EventLogEntry[]]
        $eventInfo
    )

    Process
    {
        foreach ($info in $eventInfo)
        {
            $enterSleep = [DateTime]::Parse($info.ReplacementStrings[0]);
            $exitSleep = [DateTime]::Parse($info.ReplacementStrings[1]);
            $duration = $exitSleep - $enterSleep
            $wakeSource = 'Unknown'
            if ($info.Message -match 'Wake Source:\s*(.*)$')
            {
                $wakeSource = $matches[1]
            }
            new-object psobject -Property @{Duration = $duration; Sleep = $enterSleep; 
                                            Wake = $exitSleep; WakeSource = $wakeSource}
        }
    }
}

Get-EventLog -LogName System -Source Microsoft-Windows-Power-Troubleshooter -Newest $Newest | 
     Sort TimeGenerated | Parse-EventLogEntry
}}}
eg:
PS C:\ps> .\Get-SleepInfo.ps1 5

Duration         WakeSource Sleep                 Wake
--------         ---------- -----                 ----
00:00:11.4859134 1          1/02/2016 3:12:03 AM  1/02/2016 3:12:15 AM
00:14:18.1375597 1          1/02/2016 3:20:07 AM  1/02/2016 3:34:25 AM
05:08:16.4686740 1          1/02/2016 3:48:12 AM  1/02/2016 8:56:29 AM
00:30:32.7013046 1          1/02/2016 12:05:25 PM 1/02/2016 12:35:58 PM
00:07:08.8210336 1          1/02/2016 1:00:24 PM  1/02/2016 1:07:33 PM


PS C:\ps>
http://windowssecrets.com/forums/showthread.php/164689-Schedule-a-Powershell-script-while-PC-sleeps
http://newdelhipowershellusergroup.blogspot.com.au/2014/01/powershell-tips-changing-monitor.html

http://windowsitpro.com/systems-management/how-can-i-configure-monitor-power-logon-screen
http://www.isunshare.com/windows-10/6-ways-to-turn-on-on-screen-keyboard-in-windows-10.html
http://certnew.blogspot.com.au/2013/12/how-to-script-get-scheduled-tasks-from.html
http://jon.netdork.net/2011/03/08/powershell-and-exporting-windows-scheduled-tasks/

http://haomengapp.com/questions/2131975/how-to-find-information-in-powershell
!Get a remote computers OS information
{{{
x = read-host -prompt "Please enter the machine name:"
Get-WmiObject -Class Win32_OperatingSystem -Namespace root/cimv2 -ComputerName $x | Format-List -Property Name, OSArchitecture
}}}
!Get Dell Service Tag by Reading from Text File
{{{
#Copyright 2013 - Roman Pakhlevaniants
#
#This script prompts for a path to the .txt file that contains computer names.
#If no path is specified it defaults to 'C:\temp\computers.txt' 
#The script reads each item in the file and prints the Service tag/bios information.

$x = read-host -prompt "Please enter the full path to the text file."
if ($x = " ")
{
 $path = "C:\temp\computers.txt"
}
else {$path = $x}

$computer = get-content $path
foreach ($item in $computer)
{
	get-wmiobject -computername $item -class win32_bios
}
}}}
!Get Various Remote Machine Information
https://community.spiceworks.com/scripts/show/2971-get-various-remote-machine-information
{{{
# This will run a script that will pull specific information about the requested machine
# First you must run Import-Module <location of this script> then type 'Get-Sysinfo'
# Example:  'Import-Module C:\Test\Get-Sysinfo.ps1'

Function Get-Sysinfo

{

Clear-Host

# Do NOT edit this variable
$pc = read-host -prompt "Type the machine name "  

write-host "`n"

# Remote/Local user session section
    write-host "Logged On Users" -ForegroundColor cyan
    quser.exe /SERVER:$pc


# System Information section
    write-host "`n"
    write-host "System Information" -ForegroundColor cyan
    $colItems = get-wmiobject -class "Win32_Processor" -namespace "root\CIMV2" -computername $pc
        foreach ($objItem in $colItems){
    write-host "Name: " $objItem.SystemName
    }
    
    $colItems = get-wmiobject -class "Win32_ComputerSystem" -namespace "root\CIMV2" -computername $pc
        foreach ($objItem in $colItems){
    write-host "Domain: " $objItem.Domain
    }

    $colItems = get-wmiobject -class "Win32_OperatingSystem" -namespace "root\CIMV2" -computername $pc
        foreach ($objItem in $colItems){
    $installed = ([WMI]'').ConvertToDateTime($objItem.InstallDate)
    write-host "Date of Install: " $installed
    }

    $colItems = get-wmiobject -class "Win32_ComputerSystem" -namespace "root\CIMV2" -computername $pc
        foreach ($objItem in $colItems){
    $displayGB = [math]::round($objItem.TotalPhysicalMemory/1024/1024/1024, 0)
    write-host "Manufacturer: " $objItem.Manufacturer
    write-host "Model: " $objItem.Model
    }

    $colItems = get-wmiobject -class "Win32_OperatingSystem" -namespace "root\CIMV2" -computername $pc
        foreach ($objItem in $colItems){
    write-host "OS Type: " $objItem.Caption
    write-host "OS Version: " $objItem.Version
    }

    $colItems = get-wmiobject -class "Win32_Bios" -namespace "root\CIMV2" -computername $pc
        foreach ($objItem in $colItems){
    write-host "Serial Number: " $objItem.SerialNumber
    write-host "BIOS version: " $objItem.SMBIOSBIOSVersion
    }

# Network Information section
    write-host "`n"
    write-host "Network Information" -ForegroundColor cyan
    $colItems = get-wmiobject -class "Win32_NetworkAdapterConfiguration" -Filter "IPEnabled = True" -namespace "root\CIMV2" -computername $pc
        foreach ($objItem in $colItems){
    write-host "Adapter: " $objItem.Description -ForegroundColor magenta
    write-host "IP Address: " $objItem.IPAddress
    write-host "Subnet Mask: " $objItem.IPSubnet
    write-host "Gateway: " $objItem.DefaultIPGateway
    write-host "DHCP Enabled: " $objItem.DHCPEnabled
    }

# CPU Information section
    write-host "`n"
    write-host "CPU Information" -ForegroundColor cyan
    $colItems = get-wmiobject -class "Win32_Processor" -namespace "root\CIMV2" -computername $pc
        foreach ($objItem in $colItems){
    write-host "Type: " $objItem.Name
    write-host "Cores: " $objItem.NumberofLogicalProcessors
    write-host "Family: " $objItem.Caption
    write-host "Speed: " $objItem.CurrentClockSpeed "MHz"
    }

# Memory Information section
    write-host "`n"
    $colItems = get-wmiobject -class "Win32_ComputerSystem" -namespace "root\CIMV2" -computername $pc
        foreach ($objItem in $colItems){
    $displayGB = [math]::round($objItem.TotalPhysicalMemory/1024/1024/1024, 0)
    write-host "Memory Information" -ForegroundColor cyan
    write-host "Total Physical Memory: " $displayGB "GB"
    }

# Disk Information section
    write-host "`n"
    write-host "Disk Information" -ForegroundColor cyan
    $colItems = get-wmiobject -class "Win32_LogicalDisk" -namespace "root\CIMV2" -computername $pc
        foreach ($objItem in $colItems){
    write-host "Drive: " $objItem.Name
    write-host "Name: " $objItem.VolumeName
    $displayGB = [math]::round($objItem.Size/1024/1024/1024, 0)
    write-host "Total disk size: " $displayGB "GB"
    $displayGB = [math]::round($objItem.FreeSpace/1024/1024/1024, 0)
    write-host "Free disk size: " $displayGB "GB"
    write-host "`n"
    write-host "*******************" -ForegroundColor yellow
    }

# Uptime Information section
    write-host "`n"
    write-host "Uptime Information" -ForegroundColor cyan
    $colItems = get-wmiobject -class "Win32_OperatingSystem" -namespace "root\CIMV2" -computername $pc
        foreach ($objItem in $colItems){
    $Booted = Get-WmiObject -Class Win32_OperatingSystem -computername $pc
    write-host "Last Boot: " $Booted.ConvertToDateTime($objItem.LastBootUpTime) | Format-Table Days, Hours -AutoSize
    $uptime = (Get-Date) - ($colItems.ConvertToDateTime($colItems.lastbootuptime))
    $display = "Uptime: " + $uptime.Days + " days, " + $uptime.Hours + " hours, " + $uptime.Minutes + " minutes"
    write-host $display
    }

}
}}}
!Install MSI Software Remotely
Ref: https://community.spiceworks.com/scripts/show/3136-install-msi-software-remotely
{{{
$computerlist = Get-Content -Path 'C:\PathTo\YourTextFile\computers.txt' -Force
<#
Note: computers.txt will need to have computer names in the format of:
ComputerName1
ComputerName2
ComputerName3 etc...
#>
$date = Get-Date -Format dd-MMM-yyyy_HH.mm
ForEach ($computer in $computerlist)
{
$filepathx86 = Test-Path "\\$computer\C$\Program Files\Path\To\YourProgamExecutable.exe"
$filepathx64 = Test-Path "\\$computer\C$\Program Files (x86)\Path\To\YourProgamExecutable.exe"
If ($filepathx86 -eq $false -and $filepathx64 -eq $false)
{
Copy-Item "\\YourServerName\ShareName\FolderWithYourMSIFiles\" -Destination "\\$computer\c$\windows\temp\" -Container -Recurse -Force

$InstallString = 'msiexec.exe /i /qn "C:\windows\temp\YourProgram.msi"'

(Get-WMIObject -ComputerName $computer -List | Where-Object -FilterScript {$_.Name -eq "Win32_Process"}).InvokeMethod("Create","$InstallString") 
Do
{
$Installer = Get-Process -Name YourProgram.exe -ComputerName $computer
$InstallCountdown += 1
Start-Sleep -Seconds 1
}
Until ($Installer.ProcessName -eq "YourProgram.exe" -or $InstallCountdown -eq 300)

"$computer" + "_Software_Installed_" + "$date" | Out-File -FilePath "\\YourServerName\WhereverYouWantYour\LogFiles.txt" -Append
}
Else
{
"$computer" + "_Already_Had_Software_" + "$date" | Out-File -FilePath "\\YourServerName\WhereverYouWantYour\LogFiles.txt" -Append
}
}
}}}
!Mobile devices out of sync with Office 365 accounts for entire domain exported with PowerShell to CSV file
Ref: https://community.spiceworks.com/scripts/show/2577-mobile-devices-out-of-sync-with-office-365-accounts-for-entire-domain-exported-with-powershell-to-csv-file
{{{
<#

    .PURPOSE
        Script will output a full list of mobile devices that have not
        synced in 14 days

    . EXAMPLES
        PS> InactiveMobiles.ps1

    .OUTPUT
        UserPrincipalname
        DeviceModel
        LastSuccessSync

    .NOTES
        For Wave 14 Customers change the Get-MobileDeviceStatistics to Get-ActiveSyncDeviceStatistics

    .AUTHOR
        Dan Rose

#>

function ConnectTo-ExchangeOnline 
{   
    <#
        .SYNOPSIS
            Connects to Exchange Online with tenant credentials

        .INPUT
            Tenant Username/Password

        .RETURN
            None

    #>

    # Get Credentials 
    $Office365Credentials = Get-Credential
    
    # Create remote Powershell session 
    $Script:Session = New-PSSession -ConfigurationName Microsoft.Exchange -ConnectionUri https://ps.outlook.com/powershell -Credential $Office365credentials -Authentication Basic –AllowRedirection         
 
    # Import the session 
    Import-PSSession $Session -AllowClobber | Out-Null 
} 

ConnectTo-ExchangeOnline

# Gather Mailboxes
$users = Get-Mailbox -ResultSize Unlimited 

foreach ($user in $users) {

    # Get mobiles that have not synced for the last x days
    $mobiles = Get-MobileDeviceStatistics -Mailbox $user.identity |
        where {$_.LastSuccessSync -lt (Get-Date).AddDays(-14)} |
        select DeviceModel,LastSuccessSync

   
    foreach ($mobile in $mobiles) {
    
        $ObjProperties = New-Object PSObject

        Add-Member -InputObject $ObjProperties -MemberType NoteProperty -Name "UserPrincipalName" -Value $user.userprincipalname
        Add-Member -InputObject $ObjProperties -MemberType NoteProperty -Name "DeviceModel" -Value $mobile.DeviceModel
        Add-Member -InputObject $ObjProperties -MemberType NoteProperty -Name "LastSuccessSync" -Value $mobile.LastSuccessSync

        $objProperties
    
        # Output to file
        $MobileString = "$($user.userprincipalname),$($mobile.DeviceModel),$($mobile.LastSuccessSync)"
        Out-File -FilePath "$Home\Desktop\$((Get-Date).ToString('dd-MM-yyyy'))_LastSyncMobiles.csv" -InputObject $MobileString  -Encoding UTF8 -append

    }
}

Remove-PSSession $Script:Session
}}}
!PowerShell Function: Run-RemoteCMD
Ref: https://community.spiceworks.com/scripts/show/803-powershell-function-run-remotecmd
{{{
    ##--------------------------------------------------------------------------
    ##  FUNCTION.......:  Run-RemoteCMD
    ##  PURPOSE........:  Runs commandline programs on remote computers. Any
    ##                    valid CMD.EXE command can be used, but be aware that
    ##                    the command will execute on the remote computer(s).
    ##  REQUIREMENTS...:  PowerShell v2.0
    ##  NOTES..........:  
    ##--------------------------------------------------------------------------
    function Run-RemoteCMD { 
        #Requires -Version 2.0  

        <#
        .SYNOPSIS
         Executes commands on a remote computer(s)
         For examples type:
             Get-Help Run-RemoteCMD -examples
        .DESCRIPTION
         This function uses the WMI win32_process method to execute commands on 
         a remote computer(s) via the CMD.EXE shell.
        .EXAMPLE
         Run-RemoteCMD Comp1
         Enter command to run: gpupdate /force
         
         This example will cause the command "gpupdate /force" to be executed on
         the remote computer "Comp1".
        .EXAMPLE
         Run-RemoteCMD SVR1
         Enter command to run: ipconfig /flushdns
         
         This example will flush the DNS resolver cache on the remote computer
         "SVR1".
        .EXAMPLE
         This function also accepts pipeline input (to facilitate running
         commands on multiple remote computers):
         
         get-content c:\computers.txt | Run-Remotecommand
         Enter command to run: gpupdate /force
         
         This example will execute the command "gpupdate /force" on all
         computers listed in the file "c:\computers.txt". The file with the list
         of computers should list one per line.
        .NOTES
         NAME......:  Run-RemoteCMD
         AUTHOR....:  Joe Glessner
         LAST EDIT.:  11MAR11
         CREATED...:  17AUG10
        .LINK
         http://joeit.wordpress.com/
        #>
        param( 
        [Parameter(Mandatory=$true,valuefrompipeline=$true)] 
        [string]$HostName) 
        begin { 
            $command = Read-Host " Enter command to run" 
            [string]$cmd = "CMD.EXE /C " +$command 
                            } 
        process { 
            $newproc = Invoke-WmiMethod -class Win32_process -name Create `
                -ArgumentList ($cmd) -ComputerName $HostName 
            if ($newproc.ReturnValue -eq 0 ) 
                    { Write-Output " Command $($command) invoked Sucessfully `
                        on $($HostName)" } 
                    ##----------------------------------------------------------
                    ##  if the command is sucessfully invoked it doesn't mean 
                    ##  that it did what its supposed to do, it means that the 
                    ##  command only sucessfully ran on the cmd.exe of the
                    ##  server. Syntax errors, etc.
                    ##----------------------------------------------------------                     
        } 
        End{} 
    }
}}}
!Powershell Wake on LAN
Ref:https://community.spiceworks.com/scripts/show/3119-powershell-wake-on-lan
{{{
#PowerShell WOL Script
#Run using Powershell
#Download and store WOLCMD.exe  http://www.depicus.com/wake-on-lan/wake-on-lan-cmd.aspx to machine you will run this script from.

#path to WOLCMD.exe
$ExePath="C:\Windows\System32\wolcmd.exe"

#Add Path to folder containing text file  of MAC addresses to wake up
$MAC=Get-Content -path "\Server\xyz\abc\IT\Powershell\computer\mac\MAC.txt"

#Loop to execute for each MAC in text file
foreach($obj in $MAC){
write-host $obj
$CLine=$obj+" 192.168.116.1 255.255.255.0 7"
Invoke-Expression "$ExePath $CLine" | out-Null
}
}}}
!Power Up/Down an Azure Virtual Server
Ref: Power Up/Down an Azure Virtual Server
{{{
# Script to power up/down an Azure Server

# Import the cmdlets (default installation location)
Import-Module 'C:\Program Files (x86)\Microsoft SDKs\Windows Azure\PowerShell\Azure\Azure.psd1'

# Import your own credentials, created from the Azure Publish link shown above
Import-AzurePublishSettingsFile 'c:\Subscription-credentials.publishsettings'

# Get the information regarding your subscription
Get-AzureSubscription

# Define a few variables for your own cloud service / virtual machine name
$cloudSvcName = 'Altaro'   # Name of your cloud service (from the Azure portal)
$vmName = 'Altaro'   # Name of your virtual machine (from the Azure portal)

# Command to start the Azure Server
Start-AzureVM -Force -ServiceName $cloudSvcName -Name $vmName

# Command to stop the Azure Server (uncomment the next line to use this feature...)
# Stop-AzureVM -Force -ServiceName $cloudSvcName -Name $vmName
}}}
!Remote Desktop Session Shadowing Script
Ref: https://community.spiceworks.com/scripts/show/3199-remote-desktop-session-shadowing-script
{{{
#Elevation Prompt Command:Benjamin Armstron http://blogs.msdn.com/b/virtual_pc_guy/archive/2010/09/23/a-self-elevating-powershell-script.aspx
# Get the ID and security principal of the current user account
$myWindowsID=[System.Security.Principal.WindowsIdentity]::GetCurrent()
$myWindowsPrincipal=new-object System.Security.Principal.WindowsPrincipal($myWindowsID)
 
# Get the security principal for the Administrator role
$adminRole=[System.Security.Principal.WindowsBuiltInRole]::Administrator
 
# Check to see if we are currently running "as Administrator"
if ($myWindowsPrincipal.IsInRole($adminRole))
   {
   # We are running "as Administrator" - so change the title and background color to indicate this
   $Host.UI.RawUI.WindowTitle = $myInvocation.MyCommand.Definition + "(Elevated)"
   $Host.UI.RawUI.BackgroundColor = "DarkBlue"
   clear-host
   }
else
   {
   # We are not running "as Administrator" - so relaunch as administrator
   
   # Create a new process object that starts PowerShell
   $newProcess = new-object System.Diagnostics.ProcessStartInfo "PowerShell";
   
   # Specify the current script path and name as a parameter
   $newProcess.Arguments = $myInvocation.MyCommand.Definition;
   
   # Indicate that the process should be elevated
   $newProcess.Verb = "runas";
   
   # Start the new process
   [System.Diagnostics.Process]::Start($newProcess);
   
   # Exit from the current, unelevated, process
   exit
   }
 
# Run your code that needs to be elevated here


Import-Module Remotedesktop 

Get-rdusersession -CollectionName CollectionName -ConnectionBroker ConnectionBroker.FQDN.com | Sort-Object UserName


function Select-TextItem 
{ 
PARAM  
( 
    [Parameter(Mandatory=$true)] 
    $options, 
    $displayProperty 
) 
 
    [int]$optionPrefix = 1 
    # Create menu list 
    foreach ($option in $options) 
    { 
        if ($displayProperty -eq $null) 
        { 
            Write-Host ("{0,3}: {1}" -f $optionPrefix,$option) 
        } 
        else 
        { 
            Write-Host ("{0,3}: {1}" -f $optionPrefix,$option.$displayProperty) 
        } 
        $optionPrefix++ 
    } 
    Write-Host ("{0,3}: {1}" -f 0,"To cancel")  
    [int]$response = Read-Host "Select which server to Shadow" 
    $val = $null 
    if ($response -gt 0 -and $response -le $options.Count) 
    { 
        $val = $options[$response-1] 
    } 
    return $val 
}    
 
$values = "server1.fqdn.com","server2.fqdn.com","server3.fqdn.com","etc..."
$val = Select-TextItem $values 
$val 

$sessionid=Read-Host -Prompt "Please input session number to shadow"


Mstsc.exe /V:$val /shadow:$sessionid /control /noConsentPrompt
}}}
!Remotely Enable WinRM / Powershell
Ref: https://community.spiceworks.com/scripts/show/2703-remotely-enable-winrm-powershell
{{{
Param([string]$computerName)

Function enableWinRM {
	$result = winrm id -r:$global:compName 2>$null

	Write-Host	
	if ($LastExitCode -eq 0) {
		Write-Host "WinRM already enabled on" $global:compName "..." -ForegroundColor green
	} else {
		Write-Host "Enabling WinRM on" $global:compName "..." -ForegroundColor red
		.\pstools\psexec.exe \\$global:compName -s C:\Windows\system32\winrm.cmd qc -quiet
		if ($LastExitCode -eq 0) {
			.\pstools\psservice.exe \\$global:compName restart WinRM
			$result = winrm id -r:$global:compName 2>$null
			
			if ($LastExitCode -eq 0) {Write-Host 'WinRM successfully enabled!' -ForegroundColor green}
			else {exit 1}
		} 
		else {exit 1}
	}
}

$global:compName = $computerName
enableWinRM
exit 0
}}}
!Remotely Kill Process - Powershell
Ref: https://community.spiceworks.com/scripts/show/2704-remotely-kill-process-powershell
{{{
cls 
Write-Host 'View/Kill Processes Remotely.'
$global:adminCreds = $host.ui.PromptForCredential("Need credentials", "Please enter your user name and password.", "", "")
$global:ComputerName = $null

Function enableWinRM {
	$global:ComputerName = Read-Host 'Computer Name?'

	#Remotely Enable WinRM (uses PSExec)
	.\remotely_enable_winrm.ps1 -computerName $global:ComputerName
	if ($LastExitCode -ne 0) {
		enableWinRM
	}
}

Function displayMenu (){
	$title = "List or Kill"
	$message = "Do you want to list the processes on the computer or kill one?"

	# Options
	$list = New-Object System.Management.Automation.Host.ChoiceDescription "&list", "List all processes on the computer"
	$kill = New-Object System.Management.Automation.Host.ChoiceDescription "&kill", "Kills a process."
	$exit = New-Object System.Management.Automation.Host.ChoiceDescription "&exit", "Exit"

	$options = [System.Management.Automation.Host.ChoiceDescription[]]($list, $kill, $exit)
	$result = $host.ui.PromptForChoice($title, $message, $options, 0) 
	
	switch ($result)
	{
		0 {listProcesses}
		1 {killProcess}
		2 {exit}
	}
}

Function listProcesses {
	#Get-Process -ComputerName $global:ComputerName
	Invoke-Command -ComputerName $global:ComputerName -scriptBlock {Get-Process} -credential $global:adminCreds
	displayMenu
}

Function killProcess {
	$processID = Read-Host 'Process ID?'
	Invoke-Command -ComputerName $global:ComputerName -scriptBlock {Stop-Process $args[0] -force} -ArgumentList $processID -credential $global:adminCreds
	displayMenu
}

enableWinRM
displayMenu
}}}
!remotely reboot printers
Ref: https://community.spiceworks.com/scripts/show/2930-remotely-reboot-printers
{{{
#powershell script to remotely reboot networked HP and Xerox printers
#ip values in plain text file printers.txt in the same directory as the script. ip's on separate lines.
#philgman@gmail.com

$SNMP = new-object -ComObject olePrn.OleSNMP
$ErrorActionPreference = "Continue"
<#Available choices for error action preference:
•SilentlyContinue – error messages are suppressed and execution continues.
•Stop – forces execution to stop, behaving like a terminating error.
•Continue - the default option. Errors will display and execution will continue.
•Inquire – prompt the user for input to see if we should proceed.
•Ignore – (new in v3) – the error is ignored and not logged to the error stream. Has very restricted usage scenarios.
#>

#reset the $error[0].Exception value on start and repeat on each loop
$error.clear()

#read from list
#return "Could not contact $_" if no response to ping
#return "Failed $_" if it connects but can not set the value
Get-Content printers.txt | ForEach-Object {
    if (Test-Connection $_ -Count 1 -Quiet) #test connection to ip with single ping
    {
        setsnmp
    }
     else {
        Write-Output "Could not contact $_"
    }
    if ( $error[0].Exception -match "Exception calling")
   {
        Write-Output "Failed $_"
   }  
   $error.clear()
   }

#send snmp value
# setting the integer vaue "4" to oid ".1.3.6.1.2.1.43.5.1.1.3.1" using the "private" community name forces the printer to reboot
function setsnmp 
{
$SNMP.open("$_","private",1,6000)
$SNMP.Set(".1.3.6.1.2.1.43.5.1.1.3.1",4)
}
}}}
!Remote process killer whack-a-mole
Ref: https://community.spiceworks.com/scripts/show/3353-remote-process-killer-whack-a-mole
{{{
$servers = Get-Content C:\scripts\data\Servers.txt
$ProcessName = 'yourprogram.exe'

foreach ($server in $servers){

    Write-Host "Checking for prescence of $ProcessName process on" $server

    $Processes = Get-WmiObject -Class Win32_Process -ComputerName $server -Filter "name='$ProcessName'"
 
        foreach ($process in $processes) {
        $UserName = $process.getowner().user
        $DomainName = $process.getowner().domain
        $processid = $process.handle
 
        Write-Host "Found $ProcessName `(PID $processid`) running as $domainname`\$username"

        Write-Host "PID $processid, you have been targeted for Termination!"
        $returnval = $process.terminate()
        $processid = $process.handle
 
        if($returnval.returnvalue -eq 0) {
            Write-Host "*** Success: Process $ProcessName `(PID $processid`) owned by $domainname\$username, you're Terminated! ***"
            Write-Host "--------------------------------------------------------------------------------"
            Write-Host

        }
        else {
        Write-Host "Error: Couldn't Terminate process $ProcessName `(PID $processid`) owned by $domainname\$username"
        Write-Host "--------------------------------------------------------------------------------"
        Write-Host
        }

    }
        
       
} 
}}}
!Restart a list of remote computers
Ref:https://community.spiceworks.com/scripts/show/740-restart-a-list-of-remote-computers
{{{

get-content c:\script\computers.txt | ForEach-Object { gwmi win32_operatingsystem -ComputerName $_  | ForEach-Object { $_.reboot() }}
}}}
{{{
One more method using Restart-computer cmdlet: 
Restart-Computer -ComputerName (Get-Content "C:\serverlist.txt") -force 
}}}
!SetService.PS1
Ref: https://community.spiceworks.com/scripts/show/1108-setservice-ps1
{{{
# SetService.ps1 by Brad Call of Internal IT Ltd. www.internalit.ca  @internal_it

# This will allow you to Start/Stop, Enable/Disable Services on 1 or many remote computers

# You should have PowerShell V2 installed to run correctly plus meet all remote powershell requirements

# Sets the base computer search name
$COMP= Read-Host "Enter Computer Name"

# Sets the service name to edit, name can be found with get-service
$SRV= Read-Host "Enter Name of Service"

# Sets what action is to be taken with the stated service
$ACTION= Read-Host "Enter 'STOPPED' to Stop the Service or 'RUNNING' to Start it"
 
# 
$CHANGESTARTUP= Read-Host "Does the Startup Type Need to be Changed? Y/N"
 
# Finds if the Startup type of services is to be changed  
 If ($CHANGESTARTUP -eq 'Y')
 
 { 
 # Sets option for startup type
 $STARTUPTYPE= Read-Host "Enter 'DISABLED', 'MANUAL' or 'AUTOMATIC'"
 
 # Starts or stops the service and sets the statup type
Set-Service -ComputerName $COMP -name $srv -status $ACTION -StartupType $STARTUPTYPE
 }
 
 # Alternate action if the startup type is not being changed
 Else
 
 {
 
 # Starts or stops the service
Set-Service -ComputerName $COMP -name $srv -status $ACTION
 
 }
}}}
!Shutdown or Restart Remote Machines
Ref: https://community.spiceworks.com/scripts/show/1481-shutdown-or-restart-remote-machines
{{{
#
#ROMAN PAKHLEVANYANTS - 2012
#SCRIPT WILL ACCEPT COMPUTER NAME AND PROVIDE OPTION FOR SHUTDOWN OR REBOOT.
#

$cmp = read-host "Enter computer name(s) seperated by a comma"
$computers = @($cmp)
$shutdown = New-Object System.Management.Automation.Host.ChoiceDescription "&Shutdown",""
$reboot = New-Object System.Management.Automation.Host.ChoiceDescription "&Reboot",""
$choices = [System.Management.Automation.Host.ChoiceDescription[]]($shutdown,$reboot)
$caption = "Warning!"
$message = "Shutdown or Reboot?"
$result = $Host.UI.PromptForChoice($caption,$message,$choices,0)

if($result -eq 0) { Write-Host "Shutting down:" $computers
    for ($i = 0; $i -lt $computers.Count; $i++) {ForEach-Object {Stop-Computer -computername $computers[$i] -force}}}

if($result -eq 1) { Write-Host "Restarting:" $computers 
    for ($i = 0; $i -lt $computers.Count; $i++) {ForEach-Object {Restart-Computer -computername $computers[$i] -force}}}
}}}
!Stop Server Process Per User!
Ref: https://community.spiceworks.com/scripts/show/2159-stop-server-process-per-user
{{{
<#
.Synopsis
   This cmdlet allows termination of a process in a user's session.
.DESCRIPTION
   When using RDS (terminal services) this cmdlet will allow an admin to remotely terminate a process on a specific user's session.
.EXAMPLE
   Stop-ProcessPerUser -ComputerName batcomputer -process notepad.exe -user batman

   Here we are terminating 'notepad.exe' for 'batman' on his server 'batcomputer'
#>
function Stop-ProcessPerUser
{
    [CmdletBinding()]
    Param
    (
        # Server. Specify the RDS server.
        [Parameter(Mandatory=$true, Position = 0)]
        [string]$ComputerName,

        # Process. Specify the process to end.
        [Parameter(Mandatory=$true, Position = 1)]
        [string]$Process,

        # User. Specify the user to end the process for.
        [Parameter(Mandatory=$true, Position = 2)]
        [string]$User
    )

    Begin
    {
        $PName = (Get-WmiObject -Class Win32_Process -Filter "Name= '$Process'" -ComputerName $ComputerName | 
        Where-Object { $_.GetOwner().User -eq $User })
    }
    Process
    {


        if($PName){

            Get-WmiObject -Class Win32_Process -Filter "Name= '$Process'" -ComputerName $ComputerName | 
            Where-Object { $_.GetOwner().User -eq $User } | 
            Foreach-Object { $_.Terminate() } | select ProcessName

            Write-Host "$Process has been terminated for $User on $ComputerName. Great job!" -ForegroundColor Cyan
        }
        else{
            Write-Host "'$Process' is not running for $User on $ComputerName. Double-check your parameters." -ForegroundColor Red
        }
       
    }
    End
    {
    }
}
}}}
!Test Win-RM
Ref: https://community.spiceworks.com/scripts/show/3085-test-win-rm
{{{
function Test-WinRM {

<#   
.SYNOPSIS   
    Test Windows Remote Management
  
.DESCRIPTION   
    Allows the administrator to test Windows Remote Management is working or not on 
    localhost and remote server. It will enable administrator to be able to establish 
    a quick test of the Windows Remote Management in their environment and assess 
    the possibility of executing powershell script remotely.

.PARAMETER ComputerName
    
    Specify a hostname for query.
    
.PARAMETER Test

    Specify to continous testing until stopped.
    To stop -type Control-C.
    
.EXAMPLE     
    Test-WinRM -ComputerName Redmond
    
    This initiate a Windows Remote Management test on Redmond server

.EXAMPLE
    Test-WinRM -ComputerName Contoso -Test
    True
    
    This initiate a continuous Windows Remote Management test on Contoso server until 
    user initiate to stop the test using Control-C. If Windows Remote Management not 
    running on Contoso, it will continously return False.

.EXAMPLE
    Test-WinRM -ComputerName Contoso -Verbose
    VERBOSE: WinRM - Running
    
    This initiate a Verbose output.
    
.EXAMPLE
    $Test = Test-WinRM -ComputerName Redmond ; if($Test -eq $True){ write-host "Yes!!! Eureka!!! It works!" }
    Yes!!! Eureka!!! It works!
    
    This utilises the returned boolean value as True or False for other condition statement.

.LINK
    Windows Remote Management
    http://msdn.microsoft.com/en-us/library/windows/desktop/aa384426(v=vs.85).aspx
    
    Installation and Configuration for Windows Remote Management
    http://msdn.microsoft.com/en-us/library/windows/desktop/aa384372(v=vs.85).aspx

.NOTES   

    Windows Server 2003 R2:  WinRM is not installed by default, but is available as 
    the Hardware Management feature through the Add/Remove System Components feature 
    in Control Panel under Management and Monitoring Tools.
#>

[CmdletBinding(
    SupportsShouldProcess=$True,
    ConfirmImpact='High')]
        
#define command parameters
param
(
    [Parameter(
        Mandatory=$False,
        ValueFromPipeline=$True,
        ValueFromPipelineByPropertyName=$True)]
        
        $ComputerName = 'v3016062.am.mds.honda.com'

    [Parameter(
        Mandatory=$False,
        ValueFromPipeline=$True,
        ValueFromPipelineByPropertyName=$True)]
        [Alias('T')]
        [Switch] $Test
        
)

BEGIN {

    #clear variable
    $Result = ""
}

PROCESS {

    do{
       
       try {
            
            #invoke a command to get WinRM service status
            $Result = Invoke-Command -ComputerName $ComputerName -ScriptBlock {Get-Service | Where-Object {($_.Name -eq "WinRM") -and ($_.Status -eq "Running")}} -ErrorAction Stop
            
            #success output
            if($PSBoundParameters['Verbose']) { Write-Verbose "WinRM - Running" }else{ $True}
        
        }catch{
            
            #failure output
            if($PSBoundParameters['Verbose']) { Write-Verbose "WinRM - Not Running"; Write-Error $_.ToString() }else{ $False }
        
        }
        
        #verify if -Test parameter is specified
        if($Test) { Continue }else{ Break }
    
    }while(!$Result?)
        
}

END { }

} #end of #function Test-WinRM
}}}
!Wake on LAN (WOL) Powershell from csv file
Ref: https://community.spiceworks.com/scripts/show/1891-wake-on-lan-wol-powershell-from-csv-file
{{{
<#
.SYNOPSIS
    A Wake on LAN Script that pulls in computer data from a csv file.
.DESCRIPTION
    This script pulls in computer data from a csv file and sends a Wake on 
    LAN Magic Packet to the specified computer or group of computers.

    The csv (.\computers.csv) file requires the following fields:
        name
        mac
        ip
        type
        active
        nictype
        
    name - the name of the system
    mac - the mac of the system with hex pairs separated with ':' or '-'
    ip - the ipv4 local subnet broadcast address
    type - "Desktop","Laptop","Server",or "Other"
    active - 1 for active, or 0 for inactive
    nictype - "P" for physical, or "W" for wireless NIC
    
    The script can be called by individual system name(s), by groups of
    systems.  Grouping is available by the computer type or subnet ip broadcast.  
    
    The script, by default, selects only the physical NICs.
.PARAMETER Name
    The Name Parameter selects the system names.
.PARAMETER OverrideIP
    The Override IP parameter selects a different ip address to send the magic
    packet to than what is in the csv file.
.PARAMETER ComputerType
    "Desktop","Laptop","Server","Other"
.PARAMETER SubnetBroadcastIP
    Used to select a group of computers based on their subnet's broadcast
    address.
.PARAMETER IncludeWirelessNic
    Includes wireless nics in selection.
.PARAMETER OnlyWirelessNic
    Only returns wireless nics in selection.
.PARAMETER PrintOnly
    PrintOnly will output the systems selected, but will not send the magic
    packet.
.PARAMETER ReturnFileContents
    This will return the file contents in their entirety, including systems
    with blank macs or that are marked as inactive.
.EXAMPLE
PS>wake-system.ps1 -Name SRV1

This will send a magic packet to the mac address of SRV1, assuming that the
mac is valid and SRV1 is marked as active.
.EXAMPLE
PS>wake-system.ps1 -Name SRV1,SRV2,SRV3

This will send a magic packet to SRV1, SRV2, and SRV3
.EXAMPLE
PS>wake-system.ps1 -Name SRV1 -IncludeWirlessNic

This will send a magic packet to SRV1's physical and wireless nic
.EXAMPLE
PS>wake-system.ps1 -Name SRV1 -OnlyWirelessNic

This will send a magic packet to SRV1's wireless nic only.
.EXAMPLE
PS>wake-system.ps1 -ComputerType Desktop

This will send a magic packet to all desktops.
.EXAMPLE
PS>wake-system.ps1 -ComputerType Desktop,Laptop

This will send a magic packet to all desktops and laptops.
.EXAMPLE
PS>wake-system.ps1 -SubnetBroadcastIP 192.168.50.255

This will send a magic packet to all computers with 192.168.50.255 in the 'ip'
field of the csv file.
.EXAMPLE
PS>wake-system.ps1 -ComputerType Desktop -PrintOnly

This will return the systems that have been selected, but will
not send a magic packet.  This allows you to see the selected systems
ahead of time.
.EXAMPLE
PS>wake-system.ps1 -ReturnFileContents

This returns each system in the csv file.  No magic packets are send.
#>
Param(
    [Parameter(Mandatory=$True,
               Position=0,
               ParameterSetName="Individual")]
    [String[]]
    $Name,
    
    [Parameter(ParameterSetName="Individual")]
    [Parameter(ParameterSetName="Group")]
    [String]
    $OverrideIP,
    
    [Parameter(ParameterSetName="Group")]
    [ValidateSet("Desktop","Laptop","Server","Other")]
    [Alias("Type")]
    [String[]]
    $ComputerType,
    
    [Parameter(ParameterSetName="Group")]
    [Alias("Subnet")]
    [String[]]
    $SubnetBroadcastIP,
    
    [Parameter(ParameterSetName="Individual")]
    [Parameter(ParameterSetName="Group")]
    [switch]
    $IncludeWirelessNic,
    
    [Parameter(ParameterSetName="Individual")]
    [Parameter(ParameterSetName="Group")]
    [switch]
    $OnlyWirelessNic,
    
    [Parameter(ParameterSetName="Individual")]
    [Parameter(ParameterSetName="Group")]
    [switch]
    $PrintOnly,
    
    [Parameter(Mandatory=$True,
               ParameterSetName="File")]
    [switch]
    $ReturnFileContents
)

$regex_mac = "^(?:[0-9A-F]{2}[:-]){5}(?:[0-9A-F]{2})$"
$regex_ipv4 = "^(?:(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.){3}(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)$"

if($OverrideIP -and ($OverrideIP -notmatch $regex_ipv4)){
    Throw "Invalid IP"
}

if($SubnetBroadcastIP -and ($SubnetBroadcastIP -notmatch $regex_ipv4)){
    Throw "Invalid SubnetBroadcastIP"
}

function determineIP {

    Param(
        $set
    )

    foreach($item in $set){

        $item | Add-Member -MemberType NoteProperty -Name ipaddy -Value ""
    
        if($OverrideIP){
            $item.ipaddy = [System.Net.IPAddress]::Parse($OverrideIP)
        }
        elseif(!$item.ip){
            Write-Host "$($item.name) has no ip. Using system broadcast." -BackgroundColor Black -ForegroundColor Red
            Write-Host ""
            $item.ipaddy = [System.Net.IPAddress]::Broadcast
        }
        elseif($item.ip -and ($item.ip -notmatch $regex_ipv4)){
            Write-Host "$($item.name) has invalid ip. Using system broadcast." -BackgroundColor Black -ForegroundColor Red
            Write-Host ""
            $item.ipaddy = [System.Net.IPAddress]::Broadcast
        }
        else{
            $item.ipaddy = [System.Net.IPAddress]::Parse($item.ip)
        }
    }

}

function sendMagicPacket{

    Param(
        $item
    )
    
    if ($item.mac -NotMatch '^([0-9A-F]{2}[:-]){5}([0-9A-F]{2})$') {
        Write-Host "$($item.name) : Mac address must be 6 hex bytes separated by : or -" -BackgroundColor Black -ForegroundColor Red
    } elseif (!$item.ipaddy) {
        Write-Host "$($item.name) : No IP address." -BackgroundColor Black -ForegroundColor Red
    } else {

        $macByte = $item.mac.split('-:') | %{ [byte]('0x' + $_) }
        $packet = [byte[]](,0xFF * 6)
        $packet += $macByte * 16
        
        Write-Host "Sending Magic Packet to $($item.name)."
        Write-Host "$($item.mac) at $($item.ipaddy.toString())"
        
        try{
            $UDPclient = new-Object System.Net.Sockets.UdpClient
            $UDPclient.connect($item.ipaddy,4000)
            [void]$UDPclient.Send($packet, $packet.Length)
            Write-Host "Packet sent."
        } catch {
            Write-Host "An error occurred." -BackgroundColor Black -ForegroundColor Red
        } finally {
            $UDPclient.Close()
        }
    
    }
    Write-Host ""
    
}

$data_file = ".\computers.csv"
$data = Import-CSV $data_file

$NicTypes = @()
$set = @()

if($OnlyWirelessNic){$NicTypes += 'W'}
else{
    $NicTypes += 'P'
    if($IncludeWirelessNic){
        $NicTypes += 'W'
    }
}

echo ""

switch ($psCmdlet.ParameterSetName) {

    "Individual" {
        $set = $data | where {($Name -contains $_.name) -and
                              ($_.active -ne [int]$False) -and
                              ($NicTypes -contains $_.nictype) -and
                              ($_.mac)}
        
        if ($PrintOnly) {
            $set
        } else {
            determineIP $set
            foreach($item in $set){
                sendMagicPacket $item
            }
        }
    }
    
    "Group" {
        $set = $data | where {($_.active -ne [int]$False) -and
                              ($NicTypes -contains $_.nictype) -and
                              ($_.mac)}

        if($ComputerType){
            $set = $set | where {$ComputerType -contains $_.type}
        }
                              
        if($SubnetBroadcastIP){
            $set = $set | where {$SubnetBroadcastIP -contains $_.ip}
        }

        if ($PrintOnly) {
            $set
        } else {
            determineIP $set
            foreach($item in $set){
                sendMagicPacket $item
            }
        }
    }
    
    "File" {
        $data
    }

}
}}}
!Making a timed loop in Powershell
Ref: https://mjolinor.wordpress.com/2012/01/14/making-a-timed-loop-in-powershell/
{{{
$timeout = new-timespan -Minutes 1
$sw = [diagnostics.stopwatch]::StartNew()
while ($sw.elapsed -lt $timeout){
    if (test-path c:\testfiles\somefile.txt){
        write-host "Found a file!"
        return
        }
 
    start-sleep -seconds 5
}
 
write-host "Timed out"
}}}
!PowerShell VM command
Exports virtual machine Test to the root of the D drive
{{{
PS C:\> Export-VM –Name Test –Path D:\
}}}
Exports all virtual machines to the root of the D drive. Each virtual machine will be exported to its own folder.
{{{
PS C:\> Get-VM | Export-VM –Path D:\
}}}



http://www.infoworld.com/article/2610395/windows-server/two-tricks-to-automate-the-export-of-live-vms-in-windows-server.html
http://www.zangogroup.com/infoworld/BackupVMScript.txt


Ref: https://technet.microsoft.com/en-gb/library/hh848491(v=wps.630).aspx  <== 2012R2 & 8.1
https://technet.microsoft.com/en-us/library/hh831535.aspx 
http://www.codeproject.com/Articles/223002/Reboot-and-Resume-PowerShell-Script
!1. Resolving Paths
Paths can be relative, such as “. \file.txt”. To resolve such a path and display its full path, you could use Resolve-Path:
{{{
PS> Resolve-Path .\file.txt
}}}
Unfortunately, though, Resolve-Path expects the file to really exist, so you cannot use it on hypothetical paths. To resolve all paths, whether
they exist or not, use this line instead:
{{{
PS> $ExecutionContext.SessionState.Path.GetUnresolvedProviderPathFromPSPath(‘.\file.txt’)
C:\Users\Tobias\file.txt
}}}

Ref: http://powershell.com
[[PowerShell Tips]]
!2. Sophisticated Directory Filtering in PowerShell 3.0
In PowerShell 3.0, Get-ChildItem now supports sophisticated filtering through its -Attributes parameter. To get all files in your Windows
folder or one of its subfolders that are not system files but are encrypted or compressed, use something like this:
{{{
Get-ChildItem $env:windir -Attributes !Directory+!System+Encrypted,!Directory+!System+Compressed -Recurse -ErrorAction SilentlyContinue
}}}
(Note how “!” negates the filter.)
The -Attributes parameter supports these attributes: Archive, Compressed, Device, Directory, Encrypted, Hidden, Normal,
NotContentIndexed, Offline, ReadOnly, ReparsePoint, SparseFile, System, and Temporary.

Ref: http://powershell.com
[[PowerShell Tips]]
!3. Finding Files Only or Folders Only
In PowerShell 2.0, to list only files or only folders you had to do filtering yourself:
{{{
Get-ChildItem $env:windir | Where-Object { $_.PSIsContainer -eq $true }
Get-ChildItem $env:windir | Where-Object { $_.PSIsContainer -eq $false }
}}}
In PowerShell 3.0, Get-ChildItem is smart enough to do that for you:
{{{
Get-ChildItem $env:windir -File
Get-ChildItem $env:windir -Directory
}}}
Ref: http://powershell.com
[[PowerShell Tips]]
!6. Clean Your Temp Folder with PowerShell
When disk space gets low, you may want to clean up your temporary folder. The code deletes all files that are older than 30 days to make
sure you’re not dumping anything that’s still needed:
{{{
$cutoff = (Get-Date) - (New-TimeSpan -Days 30)
$before = (Get-ChildItem $env:temp | Measure-Object Length -Sum).Sum
}}}
{{{
Get-ChildItem $env:temp |
Where-Object { $_.Length -ne $null } |
Where-Object { $_.LastWriteTime -lt $cutoff } |
# simulation only, no files and folders will be deleted
# replace -WhatIf with -Confirm to confirm each delete
# remove -WhatIf altogether to delete without confirmation (at your own risk)
Remove-Item -Force -ErrorAction SilentlyContinue -Recurse -WhatIf
}}}
{{{
$after = (Get-ChildItem $env:temp | Measure-Object Length -Sum).Sum
$freed = $before - $after
‘Cleanup freed {0:0.0} MB.’ -f ($freed/1MB)
}}}
Since deleting stuff is always risky, we left a -WhatIf in the code so you can check that you are actually deleting your temp folder and
not anything else (due to a typo for example). Once you are comfortable, remove -WhatIf to invoke the cleanup process automatically, or
replace -WhatIf by -Confirm to confirm each delete manually.
You may be surprised how much garbage can be removed.
{{{
PS> C:\Users\Tobias\Documents\temp\Untitled2.ps1
WARNING: Size of TEMP folder is currently 879,02 MB
WARNING: Freed 329,27 MB disk space
}}}
Ref: http://powershell.com
[[PowerShell Tips]]
!8. Find Open Files
To find open files on a remote system, use openfiles.exe and convert the results to rich objects. Here is a sample (replace “storage1” with
the name of a remote computer you have access permissions):
{{{
PS> openfiles /Query /S storage1 /FO CSV /V | ConvertFrom-Csv | Out-GridView
}}}
Openfiles.exe cannot find open files on the local machine (unless you configure your local machine to monitor open files).

Ref: http://powershell.com
[[PowerShell Tips]]
!9. Finding Newest or Oldest Files
In PowerShell 3.0, Measure-Object can be applied not just to numeric data but to anything that is comparable. In PowerShell 2.0, this line
would return the smallest and largest file size in your Windows folder:
{{{
Get-ChildItem $env:windir |
Measure-Object -Property Length -Minimum -Maximum |
Select-Object -Property Minimum,Maximum
}}}
In PowerShell 3.0, you could also measure properties like LastWriteTime, telling you the oldest and newest dates:
{{{
Get-ChildItem $env:windir |
Measure-Object -Property LastWriteTime -Minimum -Maximum |
Select-Object -Property Minimum,Maximum
}}}
Or, you could get the minimum and maximum start times of all the running processes. Make sure you use Where-Object to exclude any
process that has no StartTime value:
{{{
Get-Process |
Where-Object StartTime |
Measure-Object -Property StartTime -Minimum -Maximum |
Select-Object -Property Minimum,Maximum
}}}

Ref: http://powershell.com
[[PowerShell Tips]]
!10. Finding Duplicate Files
Hash tables are a great way to find duplicates. Simply use the hash table as lookup to see if the file (or element) was already added to the
hash table. The following script would find all files and folder with same name in the current folder, the Windows folder and its System32
subfolder.
{{{
Function Find-DuplicateName
{
$Input | ForEach-Object {
if ($lookup.ContainsKey($_.Name))
{
‘{0} ({1}) already exists in {2}.’ -f $_.Name, $_.FullName, $lookup.$($_.Name)
}
else
{
$lookup.Add($_.Name, $_.FullName)
}
}
}
}}}
{{{
$lookup = @{}
Get-ChildItem $home | Find-DuplicateName
Get-ChildItem $env:windir | Find-DuplicateName
Get-ChildItem $env:windir\system32 | Find-DuplicateName
}}}

Ref: http://powershell.com
[[PowerShell Tips]]
!11. Finding Old Files
Occasionally, you might want to find files that are older than a give number of days to delete or backup those. A simple filter can provide
that functionality:
{{{
Filter Filter-Age($Days=30)
{
if (($_.CreationTime -le (Get-Date).AddDays($days * -1) )) {$_}
}
}}}
Pipe the result of a Dir into the Filter-Age filter, and it will only let those files and folders pass that are at least the specified number of days
old. The following line finds all logfiles in your Windows folder that are at least 10 days old:
{{{
Dir $env:windir *.log -Recurse -ea 0 | Filter-Age -Days 10
}}}
You could easily delete or backup the resulting files. This would delete them:
{{{
Dir $env:windir *.log -Recurse -ea 0 | Filter-Age -Days 10 | Del -WhatIf
}}}


Ref: http://powershell.com
[[PowerShell Tips]]
!12. Finding System Folders
You may want to know where special folders such as MyPictures or Documents are located. The Environment .NET class provides a static
method named GetFolderPath() which provides this information. To find the location of your desktop, for example, use this:
{{{
[Environment]::GetFolderPath(‘Desktop’)
}}}
Simply specify an invalid keyword, and the exception will list all valid keywords:
{{{
PS> [Environment]::GetFolderPath(‘give me more!’)
Cannot convert argument “folder”, with value: “give me more!”, for “GetFolderPath” to type “System.
Environment+SpecialFolder”: “Cannot convert value
“give me more!” to type “System.Environment+SpecialFolder”. Error: “Unable to match the identifier
name give me more! to a valid enumerator name.
Specify one of the following enumerator names and try again: Desktop, Programs, MyDocuments,
Personal, Favorites, Startup, Recent, SendTo, StartMenu,
MyMusic, MyVideos, DesktopDirectory, MyComputer, NetworkShortcuts, Fonts, Templates,
CommonStartMenu, CommonPrograms, CommonStartup,
CommonDesktopDirectory, ApplicationData, PrinterShortcuts, LocalApplicationData, InternetCache,
Cookies, History, CommonApplicationData, Windows,
System, ProgramFiles, MyPictures, UserProfile, SystemX86, ProgramFilesX86, CommonProgramFiles,
CommonProgramFilesX86, CommonTemplates,
CommonDocuments, CommonAdminTools, AdminTools, CommonMusic, CommonPictures, CommonVideos, Resources,
LocalizedResources, CommonOemLinks, CDBurning””
}}}
Ref: http://powershell.com
[[PowerShell Tips]]
!14. Checking Total Size of Downloads-Folder
Whenever you download something with IE, by default the files get stored in your personal download folder. Often, over time a lot of
garbage can accumulate. This line tells you just how much data you store in this folder:
{{{
$folder = ”$env:userprofile\Downloads”
Get-ChildItem -Path $folder -Recurse -Force -ea 0 |
Measure-Object -Property Length -Sum |
ForEach-Object {
$sum = $_.Sum / 1MB
“Your Downloads folder currently occupies {0:#,##0.0} MB storage” -f $sum
}
}}}
You may be surprised just how much stuff has been collected there

Ref: http://powershell.com
[[PowerShell Tips]]
!20. Open File Exclusively
To open a file in a locked state so no one else can open, access, read, or write the file, you can use the low-level .NET methods like this:
{{{
$path = ”$env:temp\somefile.txt” # MUST EXIST!
if ( (Test-Path$path) -eq$false)
{
Set-Content-Value’test’-Path$path
}
$file = [System.io.File]::Open($path, ’Open’, ’Read’, ’None’)
$reader = New-Object System.IO.StreamReader($file)
$text = $reader.ReadToEnd()
$reader.Close()
Read-Host ’Press ENTER to release file!’
$file.Close()
}}}
This will lock a file and read its content. To illustrate the lock, the file will remain locked until you press ENTER.

Ref: http://powershell.com
[[PowerShell Tips]]
!21. Removing File Extensions
To remove file extensions, use .NET methods:
{{{
PS> [system.io.path]::GetFileNameWithoutExtension(‘c:\test\report.txt’)
}}}

Ref: http://powershell.com
[[PowerShell Tips]]
!22. Quickly Changing File Extensions
If you want to quickly exchange a file extension to create a “bak” backup version or generate a new file name for output, you should use
the ChangeExtension() method:
{{{
$oldpath = ‘c:\test\datei.csv’
$newpath = [System.IO.Path]::ChangeExtension($oldpath, ‘.xls’)
$oldpath
$newpath
}}}

Ref: http://powershell.com
[[PowerShell Tips]]
!38. List Hidden Files
Did you notice that Dir, ls or Get-ChildItem do not return hidden files?
To see hidden files, you need to specify the -Force parameter:
{{{
Get-ChildItem $env:windir -Force
}}}
But what if you just wanted to see hidden files only? Filter the result, for example like this:
{{{
Get-ChildItem $env:windir -Force | Where-Object { $_.Mode -like ‘*h*’ }
}}}
In PowerShell 3.0, you can also use:
{{{
Get-ChildItem $env:windir-Attributes h
}}}
Ref: http://powershell.com
[[PowerShell Tips]]
!42. Removing Illegal File Name Characters
If you need to batch-process hundreds of file names, you may want to make sure all file names are legal and automatically remove all
illegal characters. Here is how you can check for illegal file names (and optionally remove illegal characters from it):
{{{
$file = ’this*file\\is_illegal<>.txt’
$file
$pattern = ’[{0}]’ -f ([Regex]::Escape([String] `
[System.IO.Path]::GetInvalidFileNameChars()))
$newfile = [Regex]::Replace($file, $pattern,’’)
$newfile
}}}
Ref: http://powershell.com
[[PowerShell Tips]]
!4. Calculating Time Differences
Use New-TimeSpan and submit a date if you’d like to know how long it is until next Christmas. New-TimeSpan automatically compares this
date to the current date (and time) and returns the time span in a number of different formats from which you can choose.
For example, to get the time span in days, use this:
{{{
(New-TimeSpan 2013-12-25).Days
}}}
Note that future dates return negative time spans because by default, PowerShell binds the argument to -Start instead of -End. Explicitly
bind your date to -End will fix this:
{{{
$days = (New-TimeSpan -End 2013-12-25).Days
“$days days to go until next Christmas”
}}}

Ref: http://powershell.com
[[PowerShell Tips]]
!5. Using Relative Dates
Maybe you want to find files older than 14 days, or pull event log entries written in the past 24 hours. This is when you need relative dates.
You create relative dates by subtracting a given amount of time (a time span) from the current date.
This will get you the date 2 days ago:
{{{
(Get-Date) - (New-TimeSpan -Days 2)
}}}
You get the same information by using the DateTime methods:
{{{
(Get-Date).AddDays(-2)
}}}
And this would pull all error events from the System log within the past 12 hours:
{{{
Get-EventLog -LogName System -EntryType Error -After (Get-Date).AddHours(-12)
}}}

Ref: http://powershell.com
[[PowerShell Tips]]
!9. Finding Leap Years
You will find that the DateTime type supports a number of static methods to check dates. For example, you can check whether a year is a
leap year like this
{{{
[DateTime]::IsLeapYear(1904)
}}}

Ref: http://powershell.com
[[PowerShell Tips]]
!12. Converting UNIX Time
Some values in the Windows Registry are formatted using UNIX datetime format:
{{{
$Path = ‘HKLM:\Software\Microsoft\Windows NT\CurrentVersion’
Get-ItemProperty -Path $Path |
Select-Object -ExpandProperty InstallDate
}}}
The InstallDate value returns a large number. In UNIX format, dates and times are expressed in seconds passed since 1/1/1970.
Here is a little function that converts this back to real dates:
{{{
function ConvertFrom-UnixTime {
param(
[Parameter(Mandatory=$true, ValueFromPipeline=$true)]
[Int32]
$UnixTime
)
begin {
$startdate = Get-Date –Date ‘01/01/1970’
}
process {
$timespan = New-TimeSpan -Seconds $UnixTime
$startdate + $timespan
}
}
}}}
So now, you can correctly read the installation date from the Registry:
{{{
$Path = ‘HKLM:\Software\Microsoft\Windows NT\CurrentVersion’
Get-ItemProperty -Path $Path |
Select-Object -ExpandProperty InstallDate |
ConvertFrom-UnixTime
}}}
If you wanted to know the number of days since your copy of Windows was installed, calculate the time difference:
{{{
$Path = ‘HKLM:\Software\Microsoft\Windows NT\CurrentVersion’
Get-ItemProperty -Path $Path |
Select-Object -ExpandProperty InstallDate |
ConvertFrom-UnixTime |
New-TimeSpan |
Select-Object -ExpandProperty Days
}}}
Ref: http://powershell.com
[[PowerShell Tips]]
!13. Counting Work Days
Ever wanted to know how many days you need to work this month? Here’s a clever function that lists all the weekdays you want that are in
a month. By default, Get-WeekDay returns all Mondays through Fridays in the current month. You can specify different months (and years),
too, if you want to.
{{{
function Get-Weekday {
param(
$Month = $(Get-Date -Format ‘MM’),
$Year = $(Get-Date -Format ‘yyyy’),
$Days = 1..5
)
$MaxDays = [System.DateTime]::DaysInMonth($Year, $Month)
1..$MaxDays | ForEach-Object {
Get-Date -Day $_ -Month $Month -Year $Year |
Where-Object { $Days -contains $_.DayOfWeek }
}
}
}}}
{{{
PS> Get-Weekday | Measure-Object | Select-Object -ExpandProperty Count
20
}}}
You can even pick the weekdays you want to get included. The weekday ID starts with 0 (Sunday) and ends with 6 (Saturday). So this gets
you all the weekends in the current month:
{{{
PS> Get-Weekday -Days ‘Saturday’, ‘Sunday’ | Measure-Object | Select-Object -ExpandProperty Count
10
}}}
And if you know each Monday is a soccer meeting, this will tell you how many Mondays there are this month:
{{{
PS> Get-Weekday -Days ‘Monday’
}}}

Ref: http://powershell.com
[[PowerShell Tips]]
!18. Lunch Time Alert
Here’s a fun prompt function that turns your input prompt into a short prompt and displays the current path in your PowerShell window title bar. In addition, it has a lunch count down, displaying the minutes to go. Three minutes before lunch time, the prompt also emits a beep tone so you never miss the perfect time for lunch anymore.
{{{
function prompt {
$lunchtime = Get-Date -Hour 12 -Minute 30
$timespan = New-TimeSpan -End $lunchtime
[Int]$minutes = $timespan.TotalMinutes
switch ($minutes) {
{ $_ -lt 0 } { $text = ‘Lunch is over. {0}’; continue }
{ $_ -lt 3 } { $text = ‘Prepare for lunch! {0}’ }
default { $text = ‘{1} minutes to go... {0}’ }
}
‘PS> ‘
$Host.UI.RawUI.WindowTitle = $text -f (Get-Location), $minutes
if ($minutes -lt 3) { [System.Console]::Beep() }
}
}}}

Ref: http://powershell.com
[[PowerShell Tips]]
!24. Finding Computer Serial Number
Professionally-managed computer systems have an individual serial number that often is printed on the enclosure. WMI can then retrieve the serial number locally and remotely, which is a lot more convenient than climbing under the desk and reading the number from the physical enclosure:
{{{
$serial = Get-WmiObject Win32_SystemEnclosure | Select-Object -ExpandProperty serialnumber
“Computer serial number: $serial”
}}}
If no serial number is returned, then your computer hardware manufacturer did not include the information. This is sometimes the case with cheap off-the-shelf machines.

Ref: http://powershell.com
[[PowerShell Tips]]
!25. Renaming Computers
WMI can rename computers (provided you have Administrator privileges and know what you do).
The next example will read the serial number from the system enclosure class and rename the computer accordingly:
{{{
$serial = Get-WmiObject Win32_SystemEnclosure | Select-Object -ExpandProperty serialnumber
if ($serial -ne ‘None’) {
$computer = Get-WmiObject Win32_ComputerSystem
$computer.Rename(“DESKTOP_$serial”)
} else {
Write-Warning ‘Computer has no serial number’
}
}}}
Ref: http://powershell.com
[[PowerShell Tips]]
!28. Detect DHCP State
You can use WMI and Win32_NetworkAdapterConfiguration to determine whether a computer uses DHCP to acquire an IP address. Simply look for all instances where IPEnabled is true and DHCPEnabled is also true.
The next line will provide you with the number of network adapters using DHCP:
{{{
$number = Get-WmiObject Win32_NetworkAdapterConfiguration -Filter ‘IPEnabled=true and
DHCPEnabled=true’ |
Measure-Object |
Select-Object -ExpandProperty Count
“There are $number NICs with DHCP enabled”
$DHCPEnabled = $number -gt 0
“DHCPEnabled? $DHCPEnabled”
}}}

Ref: http://powershell.com
[[PowerShell Tips]]
!34. Checking System Uptime
This piece of code returns the days a given system is running since the last reboot:
{{{
$os = Get-WmiObject -Class Win32_OperatingSystem
$boottime = [System.Management.ManagementDateTimeConverter]::ToDateTime($os.LastBootupTime)
$timedifference = New-TimeSpan -Start $boottime
$days = $timedifference.TotalDays
‘Your system is running for {0:0.0} days.’ -f $days
}}}
The result looks similar to this:
{{{
Your system is running for 2,2 days.
}}}

Ref: http://powershell.com
[[PowerShell Tips]]
!1. PowerShell Support for Regular Expressions
PowerShell supports regular expressions in many operators such as -split, -replace, and -match. In addition, regular expressions can be used in conjunction with the RegEx type that provides a number of very powerful RegEx methods to find and replace text

Ref: http://powershell.com
[[PowerShell Tips]]
!2. Regular Expression Pattern Reference
Regular expressions are patterns that describe what you are looking for.
You typically compose a regular expression with three ingredients: placeholders, quantifiers, and anchors (or you simply navigate to Google and search for the regular expression pattern you need; since regular expressions are mostly platform-independent, you can grab any one you find and try it for yourself).

Regular expressions provide a number of placeholders that you can use to specifically describe what you want:
{{{
Placeholder Description
. Any character except newline (Equivalent: [^\n])
[^abc] All characters except the ones specified
[^a-z] All characters except those in the region specified
[abc] One of the characters
[a-z] One of the characters in the region
\a Bell (ASCII 7)
\c Any character allowed in XML names
\cA-\cZ Control+A to Control+Z, ASCII 1 to ASCII 26
\d Any number (Equivalent: [0-9])
\D Any non-number
\e Escape (ASCII 27)
\f Form Feed, (ASCII 12)
\n Line break
\r Carriage return
\s Any whitespace (space, tab, new line)
\S Any non-whitespace
\t tab
\w Letter, number or underline
\W Non-letter, number, or underline
}}}
In addition, you can use quantifiers. They tell RegEx how often your placeholder occurs. Without a quantifier, each placeholder alwaysrepresents exactly one instance.
{{{
Quantifier Description
* Any (no occurrence, once, many times)
? No occurrence or one occurrence
{n,} At least n occurrences
{n,m} At least n occurrences, maximum m occurrences
{n} Exactly n occurrences
+ One or many occurrences
}}}
Each quantifier by default looks for the longest match it can find (greedy). If you want to get the shortest possible match, add another “?”.
Finally, you can use anchors to tie the pattern to some position in your text. Anchors can be plain text, so “KB\d” would find any number that has a “KB” prefix. You can also use these popular anchors:
{{{
$ End of text
^ Start of text
\b Word boundary
\B No word boundary
\G After last match (no overlaps)
}}}
Regular expressions are, by default, case sensitive. When you use PowerShell operators, you control case sensitivity by picking the appropriate operator (-replace is case-insensitive, whereas -creplace is case-sensitive).
When you work with raw RegEx types and objects, prepend your expression with “(?i)” to make it case-insensitive.
You will now find many practical and working examples. Use them, or try and look up the ingredients of the regular expressions in the tables above.
Ref: http://powershell.com
[[PowerShell Tips]]
!3. Converting Semicolons and Tabs to Commas
Occasionally, you may have to convert “CSV” content to real CSV. Depending on regional settings, CSV may use commas, semicolons or tabs as delimiters. This will convert commas and tabs to semicolons:
{{{
PS> ‘Unit1,Unit2,Unit3’ -replace ‘[,\t]’, ‘;’
Unit1;Unit2;Unit3
}}}
To convert an entire file, like windowsupdate.log (which is by default tab separated), try this:
{{{
$newContent = foreach ($line in (Get-Content $env:windir\WindowsUpdate.log -ReadCount 0))
{
$line -replace ‘\t’, ‘,’
}
$header = Write-Output Date Time Code1 Code2 Type Topic Response DetailedError Code3 Code4 ID Code5
Code6 Origin InstallResult Action ActionResponse Remark
$newContent | ConvertFrom-Csv -Header $header | Out-GridView
}}}
As you see, your entire raw tab-separated log file becomes now a manageable object-oriented grid. Note that $header contains any text you want. This is a list of column headers that you can supply when your raw data input has no own column headers.
Now it is easy to get a detailed report on the latest Windows updates installed:
{{{
$newContent = foreach ($line in (Get-Content $env:windir\WindowsUpdate.log -ReadCount 0))
{
$line -replace ‘\t’, ‘,’
}
$header = Write-Output Date Time Code1 Code2 Type Topic Response DetailedError Code3 Code4 ID Code5 Code6 Origin InstallResult
Action ActionResponse Remark
$newContent |
ConvertFrom-Csv -Header $header |
Where-Object { $_.Action } |
Select-Object -Property Date, Time, Origin, Action, ActionResponse, InstallResult, Remark |
Out-GridView
}}}

Ref: http://powershell.com
[[PowerShell Tips]]
!4. Identifying and Extracting Information
The -match operator can both identify and also extract wanted information from raw text.
This is an example of identifying a pattern. This line checks to see whether the given pattern is part of the text:
{{{
$text = ‘PC678 had a problem’
$pattern = ‘PC(\d{3})’
$text -match $pattern
True
}}}
Whenever the -match is positive ($true), PowerShell also extracts the information that matched, and puts it into the $matches variable:
{{{
PS> $matches
Name                 Value
----                -----
1                  678
0                  PC678
}}}
$matches is a hash table actually. Key “0” always holds the match for the entire pattern:
{{{
PS> $matches[0]
PC678
}}}
If there are braces in your pattern, then there is additional matches information, one for each brace-pair.

Ref: http://powershell.com
[[PowerShell Tips]]
!5. Comparison Operators Turn to Filters When Applied to Arrays
Most comparison operators (including -match) work differently when applied to arrays (more than one value).
When applied to arrays, comparison operators no longer return $true or $false. Instead, they become filters. They filter out all array elements that do not match.
This would select only text that contains “IPv4”:
{{{
PS> (ipconfig) -match ‘IPv4’
IPv4 Address. . . . . . . . . . . : 172.20.10.3
}}}
And this would select only log file lines with “successfully installed” in them:
{{{
PS> (Get-Content C:\Windows\WindowsUpdate.log) -match ‘successfully installed’
}}}
So basically, while -match will only find the first match in each line, it can be used to find multiple matches in log files.
First, use -match to identify those lines in a text that contain the pattern you are after. Second, apply -match again on each of these lines to find the actual information.
This will extract recent updates from the log file windowsupdate.log inside the Windows folder:
{{{
$patternProduct = ‘update: (.*)’
$patternKB = ‘KB(\d{5,9})’
(Get-Content C:\Windows\WindowsUpdate.log) -match ‘successfully installed’ |
ForEach-Object {
$result = 1 | Select-Object -Property Date, KB, Product
if ($_ -match $patternProduct)
{
$result.Product = $matches[1]
}
if ($_ -match $patternKB)
{
$result.KB = $matches[1]
}
$result.Date = [DateTime] ($_.SubString(0,10) + ‘ ‘ + $_.SubString(11, 8))
$result
} | Out-GridView -Title ‘Recently installed updates’
}}}
Ref: http://powershell.com
[[PowerShell Tips]]
!6. Extracting IP Information from ipconfig.exe
You can apply regular expressions to any text, even text returned by native console commands like ipconfig.exe. To extract your IPv4 information, use a regular expression that looks for anything that seems to be an IP address. While there are more sophisticated regular expressions, for this task it is sufficient to look for any four numbers with a length of 1 to 3 that have dots in between them.
Also make sure your regular expression won’t identify any IPv4 address by providing an anchor such as “IPv4” or “Subnet”. Between the anchor and the actual IP address, add “.*?” which represents “anything”:
{{{
$pattern = ‘.*?((\d{1,3}\.){3}\d{1,3})’
$info = ipconfig
$ip = $info -match “IPv4$pattern” | ForEach-Object { if ($_ -match $pattern) { $matches[1] }}
$subnet = $info -match “Subnet$pattern” | ForEach-Object { if ($_ -match $pattern) { $matches[1] }}
$gateway = $info -match “Gateway$pattern” | ForEach-Object { if ($_ -match $pattern) { $matches[1]
}}
“IP: $ip Subnet: $subnet Gateway: $gateway”
}}}
When you run Get-WmiHelpLocation, it opens the web page in your default browser that documents the WMI class you specified, and also returns the URL:
{{{
PS> Get-WmiHelpLocation Win32_Share
http://msdn.microsoft.com/en-us/library/aa394435(VS.85).aspx
}}}

Ref: http://powershell.com
[[PowerShell Tips]]
!7. Removing Multiple White Spaces
Removing multiple white spaces from text is easy in PowerShell. Simply use -replace operator and look for whitespaces (“\s”) that occur one or more time (“+”), then replace them all with just one whitespace:
{{{
PS> ‘[        Man,            it    works!           ]’ -replace ‘\s+’, ‘ ‘
[ Man, it works! ]
}}}
Ref: http://powershell.com
[[PowerShell Tips]]
!8. Turning Fixed Width Columns into CSV
Replacing multiple whitespaces is a key when you need to turn fixed-width formatted text into CSV format.
Qprocess.exe, for example, is a tool that returns detailed information about running processes. This information uses fixed width columns:
{{{
PS> qprocess.exe
USERNAME SESSIONNAME ID PID IMAGE
>tobias console 1 3312 taskhost.exe
>tobias console 1 3792 dwm.exe
>tobias console 1 1172 explorer.exe
}}}
To parse those, replace two or more whitespace with one comma:
{{{
PS> (qprocess) -replace ‘\s{2,}’, ‘,’
USERNAME,SESSIONNAME,ID,PID,IMAGE
>tobias,console,1,3312,taskhost.exe
>tobias,console,1,3792,dwm.exe
>tobias,console,1,1172,explorer.exe
}}}
Now you can feed the standard CSV format into ConvertFrom-Csv, and get back real objects:
{{{
PS> (qprocess) -replace ‘\s{2,}’, ‘,’ | ConvertFrom-CSV | Format-Table
USERNAME SESSIONNAME ID PID IMAGE
-------- ----------- -- --- -----
>tobias console 1 3312 taskhost.exe
>tobias console 1 3792 dwm.exe
>tobias console 1 1172 explorer.exe
>tobias console 1 3828 bootcamp.exe
>tobias console 1 448 msseces.exe
>tobias console 1 3876 igfxtray.exe
(...)
}}}

Ref: http://powershell.com
[[PowerShell Tips]]
!9. Using Regular Expressions with Get-ChildItem
When you use Dir (alias: Get-ChildItem) to list folder contents, you can use simple wildcards but they do not give you much control.
A much more powerful approach is to use regular expressions. Since Get-ChildItem does not support regular expressions, you can use Where-Object to filter the results returned by Dir. This line will get you any file with a number in its filename, ignoring numbers in the file extension:
{{{
PS> dir $home -Recurse | Where-Object {$_.Name -match ‘\d.*?\.’} | Select-Object -ExpandProperty
Name
map1.hta
PSConfig64.EXE
03-09-2013 02-07-29.pdf
Boardingpass_X32274.pdf
mirrorfile1.txt
myAT&T v8.9.lnk
kanu1.jpg
(...)

}}}
Ref: http://powershell.com
[[PowerShell Tips]]
!10. Normalizing Paths
Sometimes, paths are not well formatted. They may contain combinations of backslashes and/or forward slashes. The -replace operator can normalize these paths because you can create a regular expression that matches both slashes and replaces them with something else:
{{{
PS> $Path = ‘C:\this/is/a\path.txt’
PS> $Path -split ‘[\/]’ -join ‘\’
C:\this\is\a\path.txt
PS> $Path -split ‘[\/]’ -join ‘\\’
C:\\this\\is\\a\\path.txt
}}}
Use square brackets to specify all the characters that you want to replace:
{{{
PS> ‘I replace commas, and also periods.’ -replace ‘[.,]’,’STOP’
I replace commasSTOP and also periodsSTOP
}}}

Ref: http://powershell.com
[[PowerShell Tips]]
!11. Replacing Multiple Instances
Regular expressions have a lot of predefined place holders such as “\W” (which represents any non-word character. You can use this to split or replace on any instance:
{{{
PS> $text = “Some sample text. This text contains [[many]] nonword chars!!!”
PS> $text -replace ‘\W’, ‘*’
Some*sample*text**This****text*contains*****many***nonword*chars***
PS> $text -replace ‘\W+’, ‘*’
Some*sample*text*This*text*contains*many*nonword*chars*
PS> $text -replace ‘\W+’, ‘$0’
Some sample text. This text contains [[many]] nonword chars!!!
PS> $text -replace ‘(\W)+’, ‘$1’
Some sample text This text contains[many nonword chars!
PS> $text -replace ‘(\W)(\1)+’, ‘$1’
Some sample text. This text contains [many] nonword chars!
}}}

Ref: http://powershell.com
[[PowerShell Tips]]
!12. Finding and Extracting Text
With regular expressions, you can easily extract matching text. Have a look:
{{{
$text = ‘The problem was discussed in KB552356. Mail feedback to tobias @powershell.com’
$pattern = ‘KB\d{4,6}’
if ($text -match $pattern)
{
$KB = $matches[0]
“The KB was $KB”
}
else
{
‘There was no KB number in the text.’
}
}}}
Ref: http://powershell.com
[[PowerShell Tips]]
!13. Splitting Without Losing Anything
When you split text, the split character by default is consumed. Thus, it is missing in the result. Here is a line that wants to get a file extension part of a path:
{{{
PS> $profile -split ‘\.’
C:\Users\Tobias\Documents\WindowsPowerShell\Microsoft
PowerShellISE_profile
ps1
}}}
It works, but the dot is gone. By using a clever trick, you can include the split character:
{{{
PS> $profile -split ‘(?=\.)’
C:\Users\Tobias\Documents\WindowsPowerShell\Microsoft
.PowerShellISE_profile
.ps1
PS> ($profile -split ‘(?=\.)’)[-1]
.ps1
}}}
This is called “look ahead”, and with “?=” you are instructing RegEx to split right after the pattern you specify (without taking out anything).
This is a very powerful technique. It lets you do much more sophisticated things. Here is an example that extracts parameters from an argument string:
{{{
PS> $commandline = ‘-Path c:\windows -Filter *.exe’
PS> $commandline -split ‘(?=-)(?<=\s)’
-Path c:\windows
-Filter *.exe
}}}
In addition to “?=”, you here also use a “look behind” (“?<=”). So this regular expression looks ahead to find a “-”, and then also looks behind to find any whitespace. Without this, it would split before any “-”.

Ref: http://powershell.com
[[PowerShell Tips]]
!14. Extracting Words
Assume you have an expression with multiple words. Words are not separated by spaces but instead by upper case letters. Using look ahead and look behind expressions, you can easily extract the words:
{{{
PS> ‘GetHostByName’ -csplit ‘(?<=[a-z])(?=[A-Z])’
Get
Host
By
Name
}}}
Ref: http://powershell.com
[[PowerShell Tips]]
!15. Scraping Information from HTML Websites
Regular expressions can extract valuable information from raw HTML. Here’s sample code that downloads HTML from any website. If you do not have direct Internet access and use a proxy and/or credentials, you will want to add more parameters to Invoke-WebRequest.
{{{
$result = Invoke-WebRequest -Uri www.powershell.com
$html = $result.Content
}}}
We could now, for example, scrape every instance of a hyperlink from that website:
{{{
$patternLink = ‘(i?)<a href=”(?<link>.*)”.*>(?<text>.*)</a>’
$MatchLink = [RegEx]$patternLink
$MatchLink.Matches($html) |
ForEach-Object { $_.Value } |
Out-GridView
}}}
You can now even access the matches found by subexpressions. Subexpressions are braces in your pattern. In the sample pattern, this is the href location and the actual text displayed:
{{{
$MatchLink.Matches($html) |
ForEach-Object {
$rv = 1 | Select-Object -Property Title, Uri
$rv.Title = $_.Groups[3].Value
$rv.Uri = $_.Groups[2].Value
$rv
} |
Out-GridView
}}}

It works!
You may argue that the result returned by Invoke-WebRequest is already clever enough to provide you this information:
{{{
$result = Invoke-WebRequest -Uri www.powershell.com
$result.Links |
Select-Object -Property outerText, href |
Out-GridView
}}}
That’s true (and truly cool), but with regular expressions you are free to scrape whatever information you want, not just the types of
information that Invoke-WebRequest has for you.
Ref: http://powershell.com
[[PowerShell Tips]]
!16. Creating Pairs of Two
If you’d have to process a long list of encoded information, let’s say a list of hexadecimal values, how would you split the list into pairs of two? Here is a way:
{{{
PS> ‘this gets splitted in pairs of two’ -split ‘(?<=\G.{2})(?=.)’
th
is
g
et
s
sp
li
tt
ed
(...)
}}}

Ref: http://powershell.com
[[PowerShell Tips]]
!17. Splitting Hex Values
This would be more specific and split only hex values:
{{{
PS> ‘00AA1CFFAB1034’ -split ‘(?<=\G[0-9a-f]{2})(?=.)’
00
AA
1C
FF
AB
10
(...)
}}}
Now it’s easy to reformat MAC addresses as well:
{{{
PS> ‘00AA1CFFAB1034’ -split ‘(?<=\G[0-9a-f]{2})(?=.)’ -join ‘:’
00:AA:1C:FF:AB:10:34
}}}
And you can also take hex dumps and convert them to decimals:
{{{
$dump = ‘00AA1CFFAB1034’
foreach ($hex in ($dump -split ‘(?<=\G[0-9a-f]{2})(?=.)’))
{
[Convert]::ToByte($hex, 16)
}
}}}

Ref: http://powershell.com
[[PowerShell Tips]]
!18. Matching Stars
Asterisk serves as a wildcard, so how would you check for the presence of an asterisk? It’s much harder than you might think:
{{{
PS> ‘Test*’ -eq ‘*’
False
PS> ‘Test*’ -like ‘**’
True
PS> ‘Test’ -like ‘**’
True
}}}
None of those work. Regular expressions do, because here you can escape (invalidate) any wildcard using the backslash (“\”):
{{{
PS> ‘Test*’ -match ‘\*’
True
PS> ‘Test’ -match ‘\*’
False
}}}
There is an even easier way that won’t require regular expressions at all:
{{{
PS> ‘Test*’.Contains(‘*’)
True
}}}
Ref: http://powershell.com
[[PowerShell Tips]]
!19. Escaping Regular Expressions
Many PowerShell operators support regular expressions: -split, -replace, and -match, for example. Because these operators expect regular expressions, your code fails if you accidentally use regex keywords like in the following command:
{{{
PS> ‘c:\test\subfolder\file.txt’ -split ‘\’
parsing “\” - Illegal \ at end of pattern.
At line:1 char:1
}}}
To make the code work, you need to escape special characters with “\”:
{{{
PS> ‘c:\test\subfolder\file.txt’ -split ‘\\’
c:
test
subfolder
file.txt
PS> (‘c:\test\subfolder\file’ -split ‘\\’)[-1]
File.txt
PS> (‘c:\test\subfolder\file’ -split ‘\\’)[0]
c:
PS> (‘c:\test\subfolder\file’ -split ‘\\’)[0,1]
c:
test
PS> (‘c:\test\subfolder\file’ -split ‘\\’)[0,1] -join ‘\’
c:\test
}}}
There is automatic escaping available so you don’t have to remember escaping yourself:
{{{
PS> [Regex]::Escape(‘\’)
\\
PS> [Regex]::Escape(‘c:\test\subfolder\file.txt’)
c:\\test\\subfolder\\file\.txt
}}}
Ref: http://powershell.com
[[PowerShell Tips]]
!20. Replacing Text
The -replace operator supports regular expressions. If you wanted to replace the last octet in an IP address by a new number, a simple replace wouldn’t let you do this. A regular expression replace turns this into a piece of cake:
{{{
PS> ‘192.168.1.200’ -replace ‘\d{1,3}$’,’201’
192.168.1.201
}}}
In this example, the RegEx pattern represents a 1-3 digit number at the end of a text (“$”). It is replaced with a new value of “201.”

Ref: http://powershell.com
[[PowerShell Tips]]
!21. Replacing Text with References to Old Values
Maybe you do not want to replace a value with a completely new static value. Instead, you might want to use part of the old match in your new value:
{{{
PS> $list = ‘server1’, ‘server2’, ‘server12’
PS> $pattern = ‘server(\d{1,3})’
PS> $list -replace $pattern, ‘VM_$1’
VM_1
VM_2
VM_12
}}}
As you can see, the server names in your list were replaced with “VM”, but the server number remained the same.
The new value used “$1” (which is not a PowerShell variable in this context, so the text must be single quoted!). This refers to the match found in the first subexpression (first braces) which happens to be the number.
Likewise, “$0” refers to the entire match:
{{{
PS> $list -replace $pattern, ‘VM_$1 (was $0 before)’
VM_1 (was server1 before)
VM_2 (was server2 before)
VM_12 (was server12 before)
}}}

Ref: http://powershell.com
[[PowerShell Tips]]
!22. Replacing Text with Calculated Values
If you want to replace text with a new text, and the new text should be a dynamic value based on the original value, the built-in Replace()
method found in the RegEx type can help. It accepts a script block that does the calculation of the replacement value.
Let’s assume you wanted to take an IP address and increment the last octet. Here is how:
{{{
[Regex]::Replace(‘192.168.1.1’, ‘\d{1,3}$’, {param($OldValue) [Int]$OldValue.Value + 1})
}}}
The script block receives one parameter called $OldValue which is the match. This object has a property called “Value” that delivers the actual old value. You have to make sure you convert this old value into the appropriate type (like a number) to do calculations. Without this,
it would be treated as string, and PowerShell would simply add a “1” to the string.

Ref: http://powershell.com
[[PowerShell Tips]]
!23. Finding Multiple RegEx Matches with Select-String
Select-String is the only built-in way of finding multiple matches. It is not very fast, but it gets the job done.
{{{
$patternEmail = ‘\b[A-Z0-9._%+-]+@[A-Z0-9.-]+\.[A-Z]{2,4}\b’
$text = “My email is tobias.weltner@email.de and also tobias@powershell.de”
$text | Select-String -AllMatches $patternEmail |
Select-Object -ExpandProperty Matches |
Select-Object -ExpandProperty Value
}}}
If you do not feel like remembering these lines all the time, create a simple filter function like this:
{{{
filter Matches($pattern) {
$_ | Select-String -AllMatches $pattern |
Select-Object -ExpandProperty Matches |
Select-Object -ExpandProperty Value
}
}}}

Now you can easily find multiple matches:
{{{
PS> $text | Matches $patternEmail
tobias.weltner@email.de
tobias@powershell.de
}}}

Ref: http://powershell.com
[[PowerShell Tips]]
!24. Finding Multiple RegEx Patterns Fast
To find all occurrences of a pattern in a text, and to find them very fast, use the .NET RegEx type. Here is a sample:
{{{
$text = ‘multiple emails like tobias.weltner@email.de and tobias@powershell.de in a string’
$patternEmail = ‘(?i)\b([A-Z0-9._%-]+@[A-Z0-9.-]+\.[A-Z]{2,4})\b’
$result = [RegEx]::Matches($text, $patternEmail)
$result.Value
}}}
This will work only in PowerShell 3.0 and above. To make the code work in any version, try this:
{{{
$text = ‘multiple emails like tobias.weltner@email.de and tobias@powershell.de in a string’
$patternEmail = ‘(?i)\b([A-Z0-9._%-]+@[A-Z0-9.-]+\.[A-Z]{2,4})\b’
$result = [RegEx]::Matches($text, $patternEmail)
Foreach ($match in $result) { $match.Value }
}}}
Note the statement “(?i)” in the regular expression pattern description. The RegEx object by default works case-sensitive. To ignore case, use this control statement.

Ref: http://powershell.com
[[PowerShell Tips]]
!25. Eliminating Duplicate Words
Let’s assume you want to eliminate duplicate words in a text. Here is how you can do this:
{{{
$text = ‘this text text contains duplicate words words following each other’
$pattern = ‘\b(\w+)(\s+\1){1,}\b’
$text -replace $pattern, ‘$1’
}}}
Basically, the pattern looks for words (“\b(\w+)”) followed by one or more whitespaces (“(\s+)”) plus the previous match (“\1”) that occurs one or more times (“{1,}”). This is then replaced by the first match (“$1”).

Ref: http://powershell.com
[[PowerShell Tips]]
!26. Extracting Email Addresses
You can create a specialized RegEx pattern matcher by converting a regular expression into the RegEx type. This generates an object that will always match the pattern you submitted.
This creates a pattern matcher for email addresses:
{{{
$MatchEmail = [RegEx]’(?i)\b[A-Z0-9._%+-]+@[A-Z0-9.-]+\.[A-Z]{2,4}\b’
}}}
To find one or more email addresses in any text, you now simply use its Matches() method:
{{{
$text = “My email is tobias.weltner@email.de and also tobias@powershell.de”
$MatchEmail.Matches($text).Value
}}}
This works in PowerShell 3.0 and better. To make it work in all versions, try this:
{{{
$MatchEmail = [RegEx]’(?i)\b[A-Z0-9._%+-]+@[A-Z0-9.-]+\.[A-Z]{2,4}\b’
$text = “My email is tobias.weltner@email.de and also tobias@powershell.
}}}
Ref: http://powershell.com
[[PowerShell Tips]]
!1. How PowerShell Functions Work
PowerShell functions use the keyword “function” to tie a keyword to a script block. Once the keyword is tied to the script block, whenever
a user enters the keyword, the script block is executed:
function Test-Function
{{{
{
‘Hello World!’
}
}}}
Curly brackets always mark code that is not executed immediately. Instead, curly brackets are used to “safely transport” PowerShell code
to someone else. So, in this scenario, the script code inside the curly brackets is safely attached to the keyword “Test-Function” without
executing it. That’s why nothing special happens when you run the function definition above.
Only when you enter the keyword you chose, the attached script block will execute:
{{{
PS> Test-Function
Hello World!
}}}
Note that PowerShell functions return anything that your script block “leaves behind”. In the example, a literal text string was returned.
PowerShell functions can return anything, though. If it is more than one item, PowerShell automatically wraps the return values into an
array.

Ref: http://powershell.com
[[PowerShell Tips]]
!2. Essential Function Best Practices
When you create your own function, here are some things you should consider:
- Function name: use cmdlet naming convention (Verb-Noun), and for verbs, stick to the list of approved verbs (run Get-Verb to see the list).
For the noun part, use a meaningful English term, and use singular, not plural. So, don’t call a function ‘ListNetworkCards’ but rather ‘Get-
NetworkCard’
- Company Prefix: To avoid name collisions, all public functions should use your very own noun-prefix. So don’t call your function “Get-
NetworkCard” because this generic name might be used elsewhere, too. Instead, pick a prefix for your company. If you work for, let’s say,
‘Global International’, a prefix could be ‘GI’, and your function name would be “Get-GINetworkCard”.
- Standard Parameter Names: Stick to meaningful standard parameter names. Don’t call a parameter -PC. Instead, call it -ComputerName.
Don’t call it -File. Instead, call it -Path. While there is no official list of approved parameter names, you should get familiar with the
parameter names used by the built-in cmdlets to get a feeling for it.
- Optional Parameters: always define at least a default value. If the user omits the parameter, then a default value ensures that the
parameter is in a defined state.
- Mandatory Parameters: always define at least a type. If the user omits the parameter and gets prompted, by defining a type you make
sure that the user input is converted into the correct type and not treated as a string (unless a string is what your parameter expects
anyway).
- Add Comment-Based Help: always add a standard help comment block so your function provides help just like cmdlets do.
All of these best practices are illustrated in a number of examples inside this document.

Ref: http://powershell.com
[[PowerShell Tips]]
!3. Defining Function Parameters
Function parameters can be defined in two ways. There is a simplified syntax like this:
{{{
function Test-Function ($Parameter1=’Default Value1’, $Parameter2=’Default Value2’)
{
“You entered $Parameter1 and $Parameter2”
}
}}}
This syntax is not best practice because PowerShell internally translates this syntax to the official syntax anyway, which looks like this:
{{{
function Test-Function
{
param($Parameter1=’Default Value1’, $Parameter2=’Default Value2’)
“You entered $Parameter1 and $Parameter2”
}
}}}
Basically, the parameter block goes inside the function and is marked with the keyword “param”.
Either way, the function returns the parameter values:
{{{
PS> Test-Function
You entered Default Value1 and Default Value2
PS> Test-Function -Parameter1 ‘New Text’
You entered New Text and Default Value2
}}}

Ref: http://.compowershell
[[PowerShell Tips]]
!4. Picking Standard Parameter Names
While you can call your parameters as you wish, to make things consistent, you should stick to standard parameter names and always
capitalize the first letter.
There is no predefined list of standard parameter names, but you can create one by looking at all the parameters from all your cmdlets:
{{{
Get-Command -CommandType Cmdlet |
ForEach-Object { $_.Parameters } |
ForEach-Object { $_.Keys } |
Group-Object -NoElement |
Sort-Object Count, Name -Descending |
Select-Object -Skip 11 |
Where-Object { $_.Count -gt 1 } |
Out-GridView
}}}
The list skips the eleven common parameters as well as parameters that occur only once. The remaining parameters are displayed in a
grid view window, and you can then use the full text search to play and find a good parameter name.

Ref: http://powershell.com
[[PowerShell Tips]]
!5. Using Mandatory Parameters
By default, parameters are optional. To make a parameter mandatory, add this declaration:
{{{
function Test-Me {
param
(
[Parameter(Mandatory=$true)]
$name
)
“You entered $name.”
}
}}}
The declaration always applies to the following parameter.
Now when you run the function without any parameters, PowerShell prompts for it:
{{{
PS> Test-Me
cmdlet Test-Me at command pipeline position 1
Supply values for the following parameters:
name:
Author
}}}
In PowerShell 3.0, the mandatory attribute defaults to $true, so you get away with:
{{{
param(
[Parameter(Mandatory)]
$p
)
}}}
However, the price you pay for this shortcut is that your function will no longer run in PowerShell 2.0.
!6. Add Help Messages to Mandatory Parameters
There are two more things to do to safely use mandatory parameters: first, add a help message so users know better what to input:
{{{
function Test-Me {
param
(
[Parameter(Mandatory=$true, HelpMessage=’Enter your name please’)]
$name
)
“You entered $name.”
}
}}}
Now when the user gets prompted, there is also a help prompt offering detailed help on “!?”:
{{{
PS> Test-Me
cmdlet Test-Me at command pipeline position 1
Supply values for the following parameters:
(Type !? for Help.)
name: !?
Enter your name please
}}}
So when the user enters “!?”, your help message appears and assists the user.
Powershell

Ref: http://powershell.com
[[PowerShell Tips]]
!7. Strongly-Typed Mandatory Parameters
To safely use mandatory parameters, aside from adding a help message, you should always strongly-type the parameter.
While you can add a data type to any parameter (and any variable in general), this is crucial for mandatory parameters. Here is why: if theuser omits the parameter and gets prompted for it, anything entered by the user will be treated as string (text). This can have weird side effects.
Here is a currency calculator that accepts EUROs and returns DOLLARs:
{{{
function Test-Me {
param
(
[Parameter(Mandatory=$true, HelpMessage=’Enter number of EUROs!’)]
$Euro
)
$Dollar = $Euro * 1.4
$Dollar
}
}}}
When you submit the argument, all is fine. When PowerShell prompts you for it, the function gets the wrong result:
{{{
PS> Test-Me -Euro 100
140
PS> Test-Me
cmdlet Test-Me at command pipeline position 1
Supply values for the following parameters:
(Type !? for Help.)
Euro: 100
100
}}}
Reason: in the second case, the user input was treated as string, so PowerShell did a string calculation, repeating the string 1.4 times
(which results in one repeated string).
Once you strongly-type the parameter, all is fine:
{{{
function Test-Me {
param
(
[Parameter(Mandatory=$true, HelpMessage=’Enter number of EUROs!’)]
[Double]
$Euro
)
$Dollar = $Euro * 1.4
$Dollar
}
}}}

Ref: http://powershell.com
[[PowerShell Tips]]
!8. Masked Mandatory Parameters
If you mark a parameter as mandatory and set its type to “SecureString,” PowerShell will automatically prompt for the password with
masked characters:
{{{
function Test-Password {
param
(
[System.Security.SecureString]
[Parameter(Mandatory=$true)]
$password
)
$plain = (New-Object System.Management.Automation.PSCredential(‘dummy’,$password)).
GetNetworkCredential().Password
“You entered: $plain”
}
}}}
The parameter will then become a SecureString which you cannot directly read. However, it is fairly easy to reconvert a SecureString back
to a plain text using an object called PSCredential as shown above.

Ref: http://powershell.com
[[PowerShell Tips]]
!9. Using Switch Parameters
Switch parameters work like a switch, so they are either “on” or “off” aka $true or $false.
To add a switch parameter to a function, cast the parameter to [switch] like this:
{{{
function Test-SwitchParameter {
param
(
[Switch]
$DoSpecial
)
if ($DoSpecial)
{
‘I am doing something special’
}
else
{
‘I am doing the usual stuff...’
}
}
}}}
Here is the result:
{{{
PS> Test-SwitchParameter
I am doing the usual stuff...
PS> Test-SwitchParameter -DoSpecial
I am doing something special
}}}
Ref: http://powershell.com
[[PowerShell Tips]]
!10. Using Parameter Set Magic
PowerShell functions do not support so-called “overloads”, but they support something similar: ParameterSets. So you can define groups
of parameters. Users can choose between these parameter groups but cannot mix the parameters from different groups.
This way, it is easy to prevent a user from combining parameters that make no particular sense.
Here is a simple example. The function Add-User either accepts a Name, a SAMAccountName or a DistinguishedName, but not a
combination of these:
{{{
function Add-User
{
[CmdletBinding(DefaultParameterSetName=’A’)]
param
(
[Parameter(ParameterSetName=’A’,Mandatory=$true)]
$Name,
[Parameter(ParameterSetName=’B’,Mandatory=$true)]
$SAMAccountName,
[Parameter(ParameterSetName=’C’,Mandatory=$true)]
$DN
)
$chosen = $PSCmdlet.ParameterSetName
“You have chosen $chosen parameter set.”
}
}}}
As you can see, the automatic variable $PSCmdlet tells you which parameter set was chosen. If the user combines parameters from different parameter sets, an error message appears.
{{{
PS> Add-User -Name test
You have chosen A parameter set.
PS> Add-User -SAMAccountName test
You have chosen B parameter set.
PS> Add-User -DN test
You have chosen C parameter set.
PS> Add-User -DN test -Name test
Add-User : Parameter set cannot be resolved using the specified named parameters.
}}}

Ref: http://powershell.com
[[PowerShell Tips]]
!11. Use Parameter Sets to Automatically Bind Data Types
You can also use parameter sets to bind input data automatically to the appropriate parameter set:
{{{
function Test-Binding {
[CmdletBinding(DefaultParameterSetName=’Name’)]
param(
[Parameter(ParameterSetName=’ID’, Position=0, Mandatory=$true)]
[Int]
$id,
[Parameter(ParameterSetName=’Name’, Position=0, Mandatory=$true)]
[String]
$name
)
$set = $PSCmdlet.ParameterSetName
“You selected $set parameter set”
if ($set -eq ‘ID’) {
“The numeric ID is $id”
} else {
“You entered $name as a name”
}
}
}}}
So now, even if the user does not use parameter names but simply inputs raw arguments,
PowerShell still automatically picks the right parameter set, based on the best-matching parameter type:
{{{
PS> Test-Binding -Name hallo
You selected Name parameter set
You entered hallo as a name
PS> Test-Binding -Id 12
You selected ID parameter set
The numeric ID is 12
PS> Test-Binding hallo
You selected Name parameter set
You entered hallo as a name
PS> Test-Binding 12
You selected ID parameter set
The numeric ID is 12
}}}

Ref: http://powershell.com
[[PowerShell Tips]]
!12. Optional and Mandatory at the Same Time
You can use parameters in multiple parameter sets and make them both optional and mandatory, depending on the situation and other parameters entered.
For example, the next function accepts two parameters: -ComputerName and -Credential. -ComputerName is optional, but if the user uses
-Credential, then -ComputerName becomes mandatory.
Here’s how you would define this:
{{{
function Connect-Somewhere
{
[CmdletBinding(DefaultParameterSetName=’A’)]
param
(
[Parameter(ParameterSetName=’A’,Mandatory=$false)]
[Parameter(ParameterSetName=’B’,Mandatory=$true)]
$ComputerName,
[Parameter(ParameterSetName=’B’,Mandatory=$false)]
$Credential
)
$chosen = $PSCmdlet.ParameterSetName
“You have chosen $chosen parameter set.”
}
}}}

Ref: http://powershell.com
[[PowerShell Tips]]
!!1. Understanding Execution Policy
Out of the box, PowerShell won’t run scripts. Whether you can run a script is governed by the “Windows PowerShell execution policy”. The currently active policy can be retrieved like this:
{{{
PS> Get-ExecutionPolicy
Restricted
}}}
End users should use the setting “RemoteSigned”. It will allow you to run local scripts but will not allow scripts from outside the network domain, or downloaded scripts from the Internet (except if the script has a valid digital signature which most scripts won’t have).
{{{
PS> Set-ExecutionPolicy RemoteSigned
PS>  Get-ExecutionPolicy
RemoteSigned
}}}
{{{
PS>Get-ExecutionPolicy LocalMachine
RemoteSigned
}}}
Professional scripters can use “Bypass” which will allow you to run any script, regardless of location. “Unrestricted” in contrast will also let you run all scripts but will pop up a confirmation each time you are trying to run a script from a “remote” location.

Here is the line to change the execution policy for your own user account:
{{{
PS> Set-ExecutionPolicy -Scope CurrentUser -ExecutionPolicy Bypass -Force
PS> Get-ExecutionPolicy
Bypass
}}}
To better understand execution policy, run this line:
{{{
PS> Get-ExecutionPolicy -List
               Scope                                              ExecutionPolicy
                -----                                                 ---------------
               MachinePolicy                                  Undefined
               UserPolicy                                       Undefined
               Process                                           Undefined
               CurrentUser                                     Bypass
               LocalMachine                                   RemoteSigned
}}}
As you can see, there are five execution policies. PowerShell goes from top to down, and the first one that is not “Undefined” becomes the effective execution policy. If all are “Undefined”, then the resulting policy is “Restricted” – that is the default behavior on new systems. Only Windows Server 2012 R2 defaults to “RemoteSigned”
The scopes “MachinePolicy” and “UserPolicy” are set by Active Directory group policies. If these are set, then they override all policies below.
The scope “Process” is valid only in the current PowerShell session. This is the policy that gets set when you run powershell.exe with the -ExecutionPolicy parameter.

Ref: http://powershell.com
[[PowerShell Tips]]
!2. Overriding Execution Policy
Execution policy is not a security boundary to protect you from evil. It is just a seat belt to protect you from yourself. That’s why there are plenty of ways to override the execution policy and execute PowerShell commands.
This approach would read a script and pipe it to powershell.exe directly (don’t forget the “-“ at the end of the command line!):
{{{
Get-Content ‘C:\somescript.ps1’ -Raw | powershell.exe -noprofile -
}}}

Ref: http://powershell.com
[[PowerShell Tips]]
!3. Listing NTFS Permissions
To view NTFS permissions for folders or files, use Get-Acl. It won’t show you the actual permissions at first, but you can make them visible like this:
{{{
Get-Acl -Path $env:windir |
Select-Object -ExpandProperty Access
}}}

Ref: http://powershell.com
[[PowerShell Tips]]
!4. Reading Security Descriptors in SDDL Form
Security descriptors work like electronic locks. They secure securable objects, such as files and folders on an NTFS drive, or registry keys, or Active Directory objects. Security descriptors typically are complex objects but can be flattened into a string representation. This string representation is called “SDDL” (Security Descriptor Definition Language), and PowerShell can display any security descriptor in SDDL form.
This outputs the SDDL for a file (make sure the file exists or specify a different file or folder):
{{{
$DogACL = Get-Acl -Path c:\test\dog.txt
$DogSDDL = $DogACL.GetSecurityDescriptorSddlForm(‘All’)
$DogSDDL
}}}
The same code could display the SDDL for a registry key. Just change the path:
{{{
$DogACL = Get-Acl -Path HKCU:\Software
$DogSDDL = $DogACL.GetSecurityDescriptorSddlForm(‘All’)
$DogSDDL
}}}

Ref: http://powershell.com
[[PowerShell Tips]]
!5. Clone NTFS Permissions
NTFS access permissions can be complex and tricky. To quickly assign NTFS permissions to a new folder, you can simply clone permissions from another folder that you know has the correct permissions applied.
Here is the first part. This creates a sample folder in your temporary folder, then opens the temporary folder and selects the newly created folder for you:
{{{
$OriginalPath = “$env:temp\sample”

New-Item -Path $OriginalPath -ItemType Directory

# manually assign correct permissions to folder “sample”
Explorer.exe “/Select,$OriginalPath”
}}}
Right-click the “sample” folder, choose “Properties”, then click on the “Security” tab. Now, add the security permissions you need and apply them.

When your “prototype” folder is correctly configured, use this code to read the security information from it:
{{{
$sddl = (Get-Acl $OriginalPath).Sddl
}}}
When you look at $sddl, it will contain a long text string that represents all the security information you just added to the folder.

From this point on, you do not need the prototype folder any more. It was needed only to create the SDDL definition string. 

You can now apply (clone) the security information to any other folder you want:
{{{
$newpath = “$env:temp\newfolder”
md $newpath
$sd = Get-Acl -Path $newpath
$sd.SetSecurityDescriptorSddlForm($sddl)
Set-Acl -Path $newpath -AclObject $sd
}}}
Unfortunately, setting ACLs this way always requires administrator privileges.
Note that you can apply this technique to any valid PowerShell path. So you can apply it to registry keys as well. Use the very same pieces of example code, and replace the file system paths with registry paths (like HKCU:\Software\SomeKey).

Ref: http://powershell.com
[[PowerShell Tips]]
!6. Adding Permissions
To add new permissions to an existing security descriptor, create an appropriate AccessRule object and configure it.
This script adds a new FileSystemAccessRule to the security descriptor of a file, granting read and write access to mydomain\myaccount.

Make sure you adjust both user account and filename before you test the code:
{{{
$colRights = [System.Security.AccessControl.FileSystemRights]’Read, Write’
$InheritanceFlag = [System.Security.AccessControl.InheritanceFlags]::None
$PropagationFlag = [System.Security.AccessControl.PropagationFlags]::None
$objType =[System.Security.AccessControl.AccessControlType]::Allow
$objUser = New-Object System.Security.Principal.NTAccount(‘mydomain\myaccount’)
$objACE = New-Object System.Security.AccessControl.FileSystemAccessRule `
($objUser, $colRights, $InheritanceFlag, $PropagationFlag, $objType)

# get original SD
$catACL = Get-Acl ‘C:\test\cat.txt’

# add permission
$catACL.AddAccessRule($objACE)

# write back the appended SD
Set-Acl ‘C:\test\cat.txt’ $catACL
}}}
You can use the same technique for other PowerShell drives, such as the registry. Just make sure you create the appropriate AccessRule object. To add permissions to registry keys, use a RegistryAccessRule object instead of a FileSystemAccessRule object.

Ref: http://powershell.com
[[PowerShell Tips]]
!7. Removing Permissions
To selectively remove a permission from a security descriptor, get access to the access control entries, pick the ones to remove, and then write back the changed security descriptor.
This example removes all permissions and denials for the account mydomain\myaccount. Make sure you adjust both account and filename before you test the code.
{{{
$catACL = Get-Acl c:\test\cat.txt

$unwanted = $catACL.Access |
Where-Object { $_.IdentityReference.Value -eq ‘mydomain\myaccount’ }

$unwanted | ForEach-Object { $null = $catACL.RemoveAccessRule($_) }

Set-Acl -Path c:\test\cat.txt -AclObject $catACL
}}}
Ref: http://powershell.com
[[PowerShell Tips]]
!8. Checking Administrator Privileges
There are numerous ways to find out if a script runs elevated. Here’s a pretty simple approach that uses whoami.exe (ships with Win7/Server 200 R2 or better):
{{{
(whoami.exe /all | Select-String S-1-16-12288) -ne $null
}}}
If you do not have whoami.exe, or if you are looking for a more integrated approach, you can use a line that is a little longer but identifies Admin status directly, without calling an external program:
{{{
(New-Object System.Security.Principal.WindowsPrincipal([System.Security.Principal.WindowsIdentity]::GetCurrent())).IsInRole([System.Security.Principal.WindowsBuiltInRole]::Administrator)
}}}

Ref: http://powershell.com
[[PowerShell Tips]]
!9. Show Admin Status in Prompt
If you want to know whether your PowerShell host has currently full Administrator privileges, here is an (admittedly long) one-liner that lets you know:
{{{
(New-Object System.Security.Principal.WindowsPrincipal([System.Security.Principal.WindowsIdentity]::GetCurrent())).IsInRole([System.Security.Principal.WindowsBuiltInRole]::Administrator)
}}}
Try executing this line in a regular PowerShell and then in an elevated shell, and check out the difference. Or, create your own console prompt which turns red when you have admin privileges:
{{{
function prompt {
if ((New-Object System.Security.Principal.WindowsPrincipal([System.Security.Principal.WindowsIdentity]::GetCurrent())).IsInRole([System.Security.Principal.WindowsBuiltInRole]::Administrator)) {
Write-Host ‘(Admin)’ –ForegroundColor Red -NoNewLine
$user = ‘Administrator: ‘
} else {
$user = ‘’
}
‘PS> ‘
$Host.UI.RawUI.WindowTitle = “$user $(Get-Location)”
}
}}}

Ref: http://powershell.com
PowerShell Tips
!10. Waiting for Elevated Processes
You can easily run a process elevated (with Administrator privileges), but if you do, you may not be able to wait for the process to complete.

Here is an example that you can try:

{{{
# launch Notepad elevated
Start-Process -FilePath notepad.exe -Verb Runas -WorkingDirectory c:\

# launch Notepad elevated and wait for it (fails in PowerShell 2.0)
Start-Process -FilePath notepad.exe -Verb Runas -WorkingDirectory c:\ -Wait

}}}
The second call will fail in PowerShell 2.0 when your calling shell was not elevated already. This is because in PowerShell 2.0, a non-elevated process can only read very limited information from an elevated process.

Ref: http://powershell.com
[[PowerShell Tips]]
!11. Executing Elevated PowerShell Code
Sometimes, a script may want to execute some portion of its code elevated, for example to write to HKLM in the Registry or change protected settings. Instead of requiring the user to run the entire script elevated, you can execute portions of it in a separate PowerShell that gets elevated automatically == provided that your user account owns Administrator privileges, or you can provide logon credentials for such an account.
This line, for example, will create a Registry key in the protected HKLM hive. If the script runs elevated already, the key will just be created. If the script has no special privileges, a UAC elevation prompt appears and elevates the script portion that needs it:
{{{
$regkeyPath = ‘HKLM:\Software\NewKey1’
# test registry key
Test-Path $regkeyPath

# code to create registry key
$code = “New-Item $regkeyPath”

# run code elevated and wait for the process (requires PowerShell 3.0, remove -Wait
for older versions)
$process = Start-Process -FilePath powershell.exe -Verb Runas -WindowStyle Minimized
-ArgumentList “-noprofile -command $code” -WorkingDirectory c:\ -Wait

# test registry key again
Test-Path $regkeyPath
}}}
Likewise, your code could execute any other piece of code that needs Administrator privileges, for example restart a service or write to a protected file location.

Ref: http://powershell.com
[[PowerShell Tips]]
!12. Requiring Administrator Privileges
If you know that a given script requires Administrator privileges, then you can mark this script with a special requirement. This will cause the entire script to fail if it was run from a non-elevated user.
This example will run if called by a user with Administrator privileges, and fail for anyone else. Note that the “requires” statement will not elevated the script.
{{{
#Requires -RunAsAdministrator
‘I am Admin!’
}}}
Note also that this statement will only work in saved scripts. It will not work in “Untitled” scripts.

Ref: http://powershell.com
[[PowerShell Tips]]
!13. Automatically Elevating Script
If you know that a script needs Administrator privileges, then you can use this code to auto-elevate the script if it is run by a non-administrator user:
{{{
$identity = [Security.Principal.WindowsIdentity]::GetCurrent()
$principal = New-Object Security.Principal.WindowsPrincipal $identity
$isAdmin = $principal.IsInRole([Security.Principal.WindowsBuiltInRole]::Administrator)

if ($isAdmin -eq $false)
{
$Script = $MyInvocation.MyCommand.Path
$Args = ‘-noprofile -nologo -executionpolicy bypass -file “{0}”’ -f $Script
Start-Process -FilePath ‘powershell.exe’ -ArgumentList $Args -Verb RunAs
exit
}

‘Running with Admin Privileges’
Read-Host ‘PRESS ENTER’
}}}
Ref: http://powershell.com
[[PowerShell Tips]]
!14. Asking for Credentials
When you write functions that accept credentials as parameters, add a transformation attribute! This way, the user can either submit a credential object (for example, a credential supplied from Get-Credential), or simply a user name as string.
The transformation attribute will then convert this string automagically into a credential and ask for a password.
Here is a sample function:
{{{
function do-something {
param(
[System.Management.Automation.Credential()]
$Credential
)
‘$Credential now holds a valid credential object’
$Credential
}
}}}

When you run do-something without parameters, it will automatically invoke the credentials dialog.

Ref: http://powershell.com
[[PowerShell Tips]]
!15. Finding Expired Certificates
To find expired certificates, you can browse the cert: drive and look for certificates that have a property NotAfter that lies in the past:
{{{
$today = Get-Date


Get-ChildItem -Path cert:\ -Recurse |
 Where-Object { $_.NotAfter } |
 Where-Object { $_.NotAfter -lt $today } |
 Select-Object -Property Subject, PSPath, NotAfter |
 Out-GridView

}}}

Ref: http://powershell.com
[[PowerShell Tips]]
!16. Deleting Installed Certificates
If you want to permanently delete a digital certificate in your certificate store, here is how. This line lists all your personal certificates:
{{{
Get-ChildItem cert:\CurrentUser\My
}}}
Let’s assume there is a certificate with a thumbprint like “5F7EAAA46548F83742D68B06148E71D4AB40A293” (replace with the thumbprint of the actual certificate you want to get rid of).

Here is how you can get and/or delete the certificate (again, make sure you change the thumbprint ID in the example to the one of the certificate you want to target on your machine):
{{{
# get certificate
Get-Item -Path cert:\CurrentUser\My\5F7EAAA46548F83742D68B06148E71D4AB40A293
# delete certificate (WARNING: THIS WILL REMOVE THE CERTIFICATE! REQUIRES POWERSHELL 3.0)
Remove-Item -Path cert:\CurrentUser\My\5F7EAAA46548F83742D68B06148E71D4AB40A293
}}}
Note that Remove-Item will not be able to delete a certificate in PowerShell 2.0. Here, you would have to resort to a low-level approach:
{{{
$cert = Get-Item -Path cert:\CurrentUser\My\5F7EAAA46548F83742D68B06148E71D4AB40A293
$store = Get-Item $cert.PSParentPath
$store.Open(‘ReadWrite’)
$store.Remove($cert)
$store.Close()
}}}

Ref: http://powershell.com
[[PowerShell Tips]]
!17. Turning User Names into SIDs
If you want to translate a valid user name to its security identifier (SID), here is a function to do that for you:
{{{
function Convert-Name2SID
{
   param
  (
     [System.Object]
     $Name,
     [System.Object]
     $Domain = $env:userdomain
  )
   $objUser = New-Object System.Security.Principal.NTAccount($domain, $name)
   $strSID = $objUser.Translate([System.Security.Principal.SecurityIdentifier])
   $strSID.Value
}
}}}

Try it with your current user name:

{{{
PS> Convert-Name2SID -Name $env:USERNAME
S-1-5-21-1907506615-3936657230-2684137421-1001
}}}

Ref: http://powershell.com
[[PowerShell Tips]]
!18. Turning SIDs into Real Names
If you just know the raw security identifier (SID), you can use the following function to translate it into real names:
{{{
function Convert-SID2User
{
  param
  (
    [Parameter(Mandatory=$true,ValueFromPipeline=$true)]
    [String]
    $SID
  )
  process
  {
    $objSID = New-Object System.Security.Principal.SecurityIdentifier($SID)
    try {
       $objUser = $objSID.Translate( [System.Security.Principal.NTAccount])
       $objUser.Value
    } catch { $SID }
  }
}
}}}
And here is a quick example on how to use it:

{{{
PS> Convert-SID2User -SID S-1-5-32-544
BUILTIN\Administrators

PS>
}}}
As you see, Convert-SID2User actually returns Identities (not just users but also groups, as you can see in this example).

Ref: http://powershell.com
[[PowerShell Tips]]
!19. Finding Profiles
To get a list of user profiles present on your machine, you can query the registry:
function Get-Profile
{{{
{
   $key = ‘HKLM:\SOFTWARE\Microsoft\Windows NT\CurrentVersion\ProfileList’
   Get-ChildItem $key -Name
}

Get-Profile

}}}
The result is a list of SIDs. With the Convert-SID2User function described before, you can now translate the SIDs to real names:

{{{
# translate SIDs to user names
# (requires the Convert-SID2User function covered before)
Get-Profile | Convert-SID2User
}}}

Ref: http://powershell.com
[[PowerShell Tips]]
!20. Finding Security Info for the Current User
With a single call to a system function, you can get a lot of security-related information about the currently logged on user (the user that is running the code):
{{{
PS> [System.Security.Principal.WindowsIdentity]::GetCurrent()

AuthenticationType  : LiveSSP
ImpersonationLevel  : None
IsAuthenticated       : True
IsGuest                  : False
IsSystem                : False
IsAnonymous          : False
Name                     : TOBI2\Tobias
Owner                    : S-1-5-21-1907506615-3936657230-2684137421-1001
User                       : S-1-5-21-1907506615-3936657230-2684137421-1001
Groups                    : {S-1-1-0, S-1-5-21-1907506615-3936657230-2684137421-1002,
S-1-5-32-559, S-1-5-32-545...}
Token                     : 4892
UserClaims             : {http://schemas.xmlsoap.org/ws/2005/05/identity/claims/nam
e: TOBI2\Tobias, http://schemas.microsoft.com/ws/2008/06/i
dentity/claims/primarysid:
S-1-5-21-1907506615-3936657230-2684137421-1001, http://sch
emas.microsoft.com/ws/2008/06/identity/claims/groupsid:
S-1-1-0, http://schemas.xmlsoap.org/ws/2005/05/identity/cl
aims/denyonlysid: S-1-5-114...}
DeviceClaims : {}
Claims : {http://schemas.xmlsoap.org/ws/2005/05/identity/claims/nam
e: TOBI2\Tobias, http://schemas.microsoft.com/ws/2008/06/i
dentity/claims/primarysid:
S-1-5-21-1907506615-3936657230-2684137421-1001, http://sch
emas.microsoft.com/ws/2008/06/identity/claims/groupsid:
S-1-1-0, http://schemas.xmlsoap.org/ws/2005/05/identity/cl
aims/denyonlysid: S-1-5-114...}
Actor :
BootstrapContext :
Label :
NameClaimType : http://schemas.xmlsoap.org/ws/2005/05/identity/claims/name
RoleClaimType : http://schemas.microsoft.com/ws/2008/06/identity/claims/gr
oupsid
}}}

To find out the user SID, for example, try this:
{{{
PS> [System.Security.Principal.WindowsIdentity]::GetCurrent().User.Value
S-1-5-21-1907506615-3936657230-2684137421-1001
}}}

Ref: http://powershell.com
[[PowerShell Tips]]
!21. Finding Current Group Memberships
To find out the groups your user belongs to, you would typically query the Active Directory. There is a much easier way, though: take a look at the user access token. This token already contains all group memberships – including nested group memberships:
{{{
PS> [System.Security.Principal.WindowsIdentity]::GetCurrent().Groups | Select-Object -ExpandProperty Value

S-1-1-0
S-1-5-21-1907506615-3936657230-2684137421-1002
S-1-5-32-559
S-1-5-32-545
S-1-5-4
S-1-2-1
S-1-5-11
S-1-5-15
S-1-11-96-3623454863-58364-18864-2661722203-1597581903-930530977-1207164330-214
1635683-1414797606-1103398013
S-1-5-113
S-1-2-0
S-1-5-64-32
}}}
You will get back the SIDs of all groups you are in. To translate the SIDs to real group names, use the Convert-SID2User function covered before:
{{{
[System.Security.Principal.WindowsIdentity]::GetCurrent().Groups |
Select-Object -ExpandProperty Value |
Convert-SID2User
}}}
You could use this approach in logon scripts to check whether a user is member of a particular group.

Ref: http://powershell.com
[[PowerShell Tips]]
!22. Generate Random Passwords
Here is a line that can create simple random passwords. Simply put the characters that you would allow in your passwords into the string. Omit characters that can be confusing, like “0OoQ” or “1lI”.
{{{
$allowed = ‘abcdefghiklmnprstuvwxyzABCDEFGHKLMNPRSTUVWXYZ123456789!”$%&=#*’
-join (Get-Random -InputObject $allowed.ToCharArray() -Count 20)
}}}

Ref: http://powershell.com
[[PowerShell Tips]]
!23. Encrypt Files with EFS
EFS (Encrypting File System) makes sure that a file can only be read by the person that encrypted it. This can be a quick and easy way for you to store sensitive information like passwords. The following code would use PowerShell to encrypt a file. This will work only if EFS is enabled on your system.
{{{
$file = Get-Item -Path c:\somefile.txt
$file.Encrypt()
# to decrypt, use this:
#$file.Decrypt()
}}}
If a file was successfully encrypted by EFS, it will turn green in the File Explorer.

Ref: http://powershell.com
[[PowerShell Tips]]
!24. Entering Passwords Securely
You can use Read-Host with the -AsSecureString parameter to enter a password with hidden characters:
{{{
$password = Read-Host -AsSecureString ‘Password’
}}}
This will return a secure string. To convert the secure string back to a plain string, use this:
{{{
$passwordPlain = (New-Object System.Management.AUtomation.PSCredential(
‘dummy’,$password)).GetNetworkCredential().Password
}}}
So this would be a function you can use to ask for a hidden password and use the plain text entered in your script:
{{{
function Get-PasswordString
{
  param
  (
     $Prompt = ‘Enter Password’
   )

   $password = Read-Host -AsSecureString $Prompt
   (New-Object System.Management.AUtomation.PSCredential(‘dummy’,$password)).
GetNetworkCredential().password
}
}}}

Ref: http://powershell.com
[[PowerShell Tips]]
!25. Decrypting SecureStrings
SecureStrings are encrypted text strings. The encryption helps protect the string content if it has to travel to another computer
(i.e. network passwords). It is obviously not protecting the string from the one who encrypted it in the first place.
Here is code to proof this: it asks for a SecureString (similar to the previous example), and then uses a system function to decrypt
it again:
{{{
$SecureString = Read-Host -AsSecureString ‘Secret’
[Runtime.InteropServices.Marshal]::PtrToStringAuto(
[Runtime.InteropServices.Marshal]::SecureStringToBSTR( $SecureString))
}}}

Ref: http://powershell.com
[[PowerShell Tips]]
!26. Unattended Authentication
Typically, when you use credentials to log on as someone else, PowerShell cmdlets will open a dialog where you can enter your
username and password.

To run commands unattended, you can create a credential object yourself. Note however that this would require you to hardcode
the password in your script which is a very risky technique.

This example would run Notepad as “companydomain\user1” without popping up a credentials dialog:
{{{
$user = ‘companydomain\User1’
$password = ‘P@ssw0rd1’ | ConvertTo-SecureString -AsPlainText -Force

$cred = New-Object System.Management.Automation.PSCredential($user, $password)

Start-Process notepad.exe -Credential $cred -LoadUserProfile
}}}

Ref: http://powershell.com
[[PowerShell Tips]]
!Find process owner
{{{
In order to find a process owner you must use WMI;

(Get-WmiObject -Class win32_process |Where-Object {$_.name -eq 'powershell.exe'}).getowner().user

to retrive all processes owned by a user:

Get-WmiObject -Class win32_process | Where-Object {$_.getowner().user -eq 'username'}
}}}
Ref: http://use-powershell.blogspot.com.au/2012/08/find-process-owner.html
http://www.tomsitpro.com/articles/powershell-for-storage,2-764.html
/***
|''Name:''|PasswordOptionPlugin|
|''Description:''|Extends TiddlyWiki options with non encrypted password option.|
|''Version:''|1.0.2|
|''Date:''|Apr 19, 2007|
|''Source:''|http://tiddlywiki.bidix.info/#PasswordOptionPlugin|
|''Author:''|BidiX (BidiX (at) bidix (dot) info)|
|''License:''|[[BSD open source license|http://tiddlywiki.bidix.info/#%5B%5BBSD%20open%20source%20license%5D%5D ]]|
|''~CoreVersion:''|2.2.0 (Beta 5)|
***/
//{{{
version.extensions.PasswordOptionPlugin = {
	major: 1, minor: 0, revision: 2, 
	date: new Date("Apr 19, 2007"),
	source: 'http://tiddlywiki.bidix.info/#PasswordOptionPlugin',
	author: 'BidiX (BidiX (at) bidix (dot) info',
	license: '[[BSD open source license|http://tiddlywiki.bidix.info/#%5B%5BBSD%20open%20source%20license%5D%5D]]',
	coreVersion: '2.2.0 (Beta 5)'
};

config.macros.option.passwordCheckboxLabel = "Save this password on this computer";
config.macros.option.passwordInputType = "password"; // password | text
setStylesheet(".pasOptionInput {width: 11em;}\n","passwordInputTypeStyle");

merge(config.macros.option.types, {
	'pas': {
		elementType: "input",
		valueField: "value",
		eventName: "onkeyup",
		className: "pasOptionInput",
		typeValue: config.macros.option.passwordInputType,
		create: function(place,type,opt,className,desc) {
			// password field
			config.macros.option.genericCreate(place,'pas',opt,className,desc);
			// checkbox linked with this password "save this password on this computer"
			config.macros.option.genericCreate(place,'chk','chk'+opt,className,desc);			
			// text savePasswordCheckboxLabel
			place.appendChild(document.createTextNode(config.macros.option.passwordCheckboxLabel));
		},
		onChange: config.macros.option.genericOnChange
	}
});

merge(config.optionHandlers['chk'], {
	get: function(name) {
		// is there an option linked with this chk ?
		var opt = name.substr(3);
		if (config.options[opt]) 
			saveOptionCookie(opt);
		return config.options[name] ? "true" : "false";
	}
});

merge(config.optionHandlers, {
	'pas': {
 		get: function(name) {
			if (config.options["chk"+name]) {
				return encodeCookie(config.options[name].toString());
			} else {
				return "";
			}
		},
		set: function(name,value) {config.options[name] = decodeCookie(value);}
	}
});

// need to reload options to load passwordOptions
loadOptionsCookie();

/*
if (!config.options['pasPassword'])
	config.options['pasPassword'] = '';

merge(config.optionsDesc,{
		pasPassword: "Test password"
	});
*/
//}}}
[[01.01 Resolving Paths|PT0101]]
[[01.02 Sophisticated Directory Filtering in PowerShell 3.0|PT0102]]
[[01.03 Finding Files Only or Folders Only|PT0103]]
[[01.04 Adding Personal Drives in PowerShell|PT0104]]
[[01.05 Discovering File System-related Cmdlets|PT0105]]
[[01.06 Clean Your Temp Folder with PowerShell|PT0106]]
[[01.07 Unblocking and Unpacking ZIP Files|PT0107]]
[[01.08 Find Open Files|PT0108]]
[[01.09 Finding Newest or Oldest Files|PT0109]]
[[01.10 Finding Duplicate Files|PT0110]]
[[01.11 Finding Old Files|PT0111]]
[[01.12 Finding System Folders|PT0112]]
[[01.13 Hiding Drive Letters|PT0113]]
[[01.14 Checking Total Size of Downloads-Folder|PT0114]]
[[01.15 Sharing Folders|PT0115]]
[[01.16 Shrinking Paths|PT0116]]
[[01.17 How Large Are My Folders?|PT0117]]
[[01.18 Bulk-Renaming Files|PT0118]]
[[01.19 Monitoring Folder Content|PT0119]]
[[01.20 Open File Exclusively|PT0120]]
[[01.21 Removing File Extensions|PT0121]]
[[01.22 Quickly Changing File Extensions|PT0122]]
[[01.23 Grouping Files Based on Size|PT0123]]
[[01.24 Open Many Files with One Command|PT0124]]
[[01.25 Use Multiple Wildcards|PT0125]]
[[01.26 Filtering Multiple File Types|PT0126]]
[[01.27 Creating Shortcuts on Your Desktop|PT0127]]
[[01.28 Create Files and Folders in One Step|PT0128]]
[[01.29 Remove Recents Folder|PT0129]]
[[01.30 Displaying Hex Dumps|PT0130]]
[[01.31 Reading File "Magic Number"|PT0131]]
[[01.32 Rename Drive Label|PT0132]]
[[01.33 No Need for Virtual Drives|PT0133]]
[[01.34 Temporary File Name|PT0134]]
[[01.35 Creating Large Dummy Files with .NET|PT0135]]
[[01.36 Does a Folder Contain a Specific File?|PT0136]]
[[01.37 File or Folder? Find Out!|PT0137]]
[[01.38 List Hidden Files|PT0138]]
[[01.39 Converting File System to NTFS|PT0139]]
[[01.40 Reading and Writing Drive Labels|PT0140]]
[[01.41 Determining a Drives' File System|PT0141]]
[[01.42 Removing Illegal File Name Characters|PT0142]]
[[01.43 Using Simple Path Analysis|PT0143]]
[[01.44 Getting Real Paths|PT0144]]
[[01.45 Select Folder-Dialog|PT0145]]
[[01.46 Quick Drive Info|PT0146]]
[[03.01 Getting Weekdays and Current Month|PT0301]]
[[03.02 Filtering Day of Week|PT0302]]
[[03.03 Display Work Hours in Prompt|PT0303]]
[[03.04 Calculating Time Differences|PT0304]]
[[03.05 Using Relative Dates|PT0305]]
[[03.06 Finding Out About DateTime Methods|PT0306]]
[[03.07 Secret Time Span Shortcuts|PT0307]]
[[03.08 Getting Short Dates|PT0308]]
[[03.09 Finding Leap Years|PT0309]]
[[03.10 Finding Days in Month|PT0310]]
[[03.11 Calculate Time Zones|PT0311]]
[[03.12 Converting UNIX Time|PT0312]]
[[03.13 Counting Work Days|PT0313]]
[[03.14 Getting Time Zones|PT0314]]
[[03.15 Parsing Date and Time|PT0315]]
[[03.16 Using Culture-Neutral Date and Time Formats|PT0316]]
[[03.17 Get Localized Day Names|PT0317]]
[[03.18 Lunch Time Alert|PT0318]]
[[03.19 Testing Numbers and Date|PT0319]]
[[03.20 Adding Clock to PowerShell Console|PT0320]]
[[03.21 Converting User Input to Date|PT0321]]
[[03.22 Using Cultures|PT0322]]
[[03.23 Listing Available Culture IDs|PT0323]]
[[03.24 Translating Culture IDs to Country Names|PT0324]]
[[04.01 Discovering Objects and Types|PT0401]]
[[04.02 Assigning Better Data Types|PT0402]]
[[04.03 Useful Data Conversions|PT0403]]
[[04.04 Chaining Type Conversions|PT0404]]
[[04.05 Sorting Specific Types|PT0405]]
[[04.06 Using Converter Class|PT0406]]
[[04.07 Converting to Signed Number|PT0407]]
[[04.08 Converting to Signed Number Using Casting|PT0408]]
[[04.09 Converting Letters to Numbers and Bit Masks|PT0409]]
[[04.10 Finding Static Methods|PT0410]]
[[04.11 Using Static Properties|PT0411]]
[[04.12 Using Static Methods|PT0412]]
[[04.13 Resolving Host Name|PT0413]]
[[04.14 Stripping Decimals without Rounding|PT0414]]
[[04.15 Generate a New GUID|PT0415]]
[[04.16 Get .NET Runtime Directory|PT0416]]
[[04.17 Extracting Icons with PowerShell|PT0417]]
[[04.18 Creating Your Own Type|PT0418]]
[[04.19 Create Custom Enumerations|PT0419]]
[[04.20 Finding Existing Enumeration Data Types|PT0420]]
[[04.21 Get List of Type Accelerators|PT0421]]
[[04.22 Working with Objects|PT0422]]
[[04.23 Examining Object Data|PT0423]]
[[04.24 Converting to Hex|PT0424]]
[[04.25 Creating New Objects|PT0425]]
[[04.26 Using Constructors to Create New Objects|PT0426]]
[[04.27 Displaying All Object Properties|PT0427]]
[[04.28 Using COM Objects|PT0428]]
[[04.29 Listing Windows Updates|PT0429]]
[[04.30 Controlling Automatic Updates|PT0430]]
[[04.31 Controlling Automatic Updates Installation Time|PT0431]]
[[04.32 Opening MsgBoxes|PT0432]]
[[04.33 Creating Custom Objects|PT0433]]
[[04.34 Creating Custom Objects with Select-Object|PT0434]]
[[04.35 Creating New Objects the JSON Way|PT0435]]
[[04.36 Creating Objects in PowerShell 3.0 (Fast and Easy)|PT0436]]
[[04.37 Discover Hidden Object Members|PT0437]]
[[04.38 Renaming Object Properties in PowerShell|PT0438]]
[[04.39 Getting Help for Objects - Online|PT0439]]
[[04.40 Finding Useful .NET Types|PT0440]]
[[04.41 Checking Loaded Assemblies|PT0441]]
[[04.42 Finding Methods with Specific Keywords|PT0442]]
[[05.01 How WMI Works|PT0501]]
[[05.02 Finding WMI Class Names|PT0502]]
[[05.03 Find Useful WMI Classes|PT0503]]
[[05.04 Finding Commonly Used WMI Classes|PT0504]]
[[05.05 Finding All Object Properties|PT0505]]
[[05.06 Getting WMI Help|PT0506]]
[[05.07 Check Windows License Status|PT0507]]
[[05.08 Listing All WMI Namespaces|PT0508]]
[[05.09 Listing Power Plans|PT0509]]
[[05.10 Determining Service Start Modes|PT0510]]
[[05.11 Identifying Computer Hardware|PT0511]]
[[05.12 Get Logged-On User|PT0512]]
[[05.13 Get All Logged-On Users|PT0513]]
[[05.14 Finding IP and MAC Addresses|PT0514]]
[[05.15 Finding Services and Filtering Results|PT0515]]
[[05.16 WMI Server-Side Filtering|PT0516]]
[[05.17 Remove Empty Results|PT0517]]
[[05.18 Getting IPv4 Addresses|PT0518]]
[[05.19 Finding Unused Drives|PT0519]]
[[05.20 List Local Groups|PT0520]]
[[05.21 Check for a Battery|PT0521]]
[[05.22 Displaying Battery Charge in Your Prompt|PT0522]]
[[05.23 Averaging Multiple Objects|PT0523]]
[[05.24 Finding Computer Serial Number|PT0524]]
[[05.25 Renaming Computers|PT0525]]
[[05.26 Use WMI and WQL!|PT0526]]
[[05.27 Accessing Individual Files and Folders Remotely via WMI|PT0527]]
[[05.28 Detect DHCP State|PT0528]]
[[05.29 Map Network Drive|PT0529]]
[[05.30 Use WMI to Create Hardware Inventory|PT0530]]
[[05.31 Check Active Internet Connection|PT0531]]
[[05.32 Finding Out Video Resolution|PT0532]]
[[05.33 Converting WMI Date and Time|PT0533]]
[[05.34 Checking System Uptime|PT0534]]
[[05.35 Free Space on Disks|PT0535]]
[[05.36 Backing Up Event Log Files|PT0536]]
[[05.37 Translate EventID to InstanceID|PT0537]]
[[05.38 Formatting a Drive|PT0538]]
[[05.39 Disabling Automatic Page Files|PT0539]]
[[05.40 Enumerating Network Adapters|PT0540]]
[[05.41 Resetting Network Adapters|PT0541]]
[[05.42 Finding WMI Instance Path Names|PT0542]]
[[05.43 Accessing WMI Instances Directly|PT0543]]
[[05.44 View Object Inheritance|PT0544]]
[[05.45 Calling ChkDsk via WMI|PT0545]]
[[05.46 Calculating Server Uptime|PT0546]]
[[05.47 Get Running Process Owners|PT0547]]
[[05.48 Forwarding Selected Parameters with PowerShell|PT0548]]
[[05.49 Listing Processes and Process Ownership|PT0549]]
[[05.50 Get Process Owners|PT0550]]
[[05.51 Change Service Account Password|PT0551]]
[[05.52 Using Clear Text Descriptions|PT0552]]
[[05.53 How Much RAM Do You Have?|PT0553]]
[[05.54 Create HTML System Reports|PT0554]]
[[05.55 Creating HTML Reports|PT0555]]
[[05.56 Printing Results|PT0556]]
[[05.57 Combining Objects|PT0557]]
[[05.58 Removing Empty Object Properties|PT0558]]
[[06.01 PowerShell Support for Regular Expressions|PT0601]]
[[06.02 Regular Expression Pattern Reference|PT0602]]
[[06.03 Converting Semicolons and Tabs to Commas|PT0603]]
[[06.04 Identifying and Extracting Information|PT0604]]
[[06.05 Comparison Operators Turn to Filters When Applied to Arrays|PT0605]]
[[06.06 Extracting IP Information from ipconfig.exe|PT0606]]
[[06.07 Removing Multiple White Spaces|PT0607]]
[[06.08 Turning Fixed Width Columns into CSV|PT0608]]
[[06.09 Using Regular Expressions with Get-ChildItem|PT0609]]
[[06.10 Normalizing Paths|PT0610]]
[[06.11 Replacing Multiple Instances|PT0611]]
[[06.12 Finding and Extracting Text|PT0612]]
[[06.13 Splitting Without Losing Anything|PT0613]]
[[06.14 Extracting Words|PT0614]]
[[06.15 Scraping Information from HTML Websites|PT0615]]
[[06.16 Creating Pairs of Two|PT0616]]
[[06.17 Splitting Hex Values|PT0617]]
[[06.18 Matching Stars|PT0618]]
[[06.19 Escaping Regular Expressions|PT0619]]
[[06.20 Replacing Text|PT0620]]
[[06.21 Replacing Text with References to Old Values|PT0621]]
[[06.22 Replacing Text with Calculated Values|PT0622]]
[[06.23 Finding Multiple RegEx Matches with Select-String|PT0623]]
[[06.24 Finding Multiple RegEx Patterns Fast|PT0624]]
[[06.25 Eliminating Duplicate Words|PT0625]]
[[06.26 Extracting Email Addresses|PT0626]]
[[07.01 How PowerShell Functions Work|PT0701]]
[[07.02 Essential Function Best Practices|PT0702]]
[[07.03 Defining Function Parameters|PT0703]]
[[07.04 Picking Standard Parameter Names|PT0704]]
[[07.05 Using Mandatory Parameters|PT0705]]
[[07.06 Add Help Messages to Mandatory Parameters|PT0706]]
[[07.07 Strongly-Typed Mandatory Parameters|PT0707]]
[[07.08 Masked Mandatory Parameters|PT0708]]
[[07.09 Using Switch Parameters|PT0709]]
[[07.10 Using Parameter Set Magic|PT0710]]
[[07.11 Use Parameter Sets to Automatically Bind Data Types|PT0711]]
[[07.12 Optional and Mandatory at the Same Time|PT0712]]
[[07.13 Limiting Number of Arguments|PT0713]]
[[07.14 Rich IntelliSense for Function Arguments|PT0714]]
[[07.15 Using Enumeration Types for Parameter IntelliSense|PT0715]]
[[07.16 Validating Arguments Using Patterns|PT0716]]
[[07.17 Evaluating User Submitted Parameters|PT0717]]
[[07.18 Splatting Parameters|PT0718]]
[[07.19 Forwarding Parameters|PT0719]]
[[07.20 Exiting a Function|PT0720]]
[[07.21 Defining Return Values|PT0721]]
[[07.22 Declaring Function Return Type|PT0722]]
[[07.23 Accepting Pipeline Data in Realtime|PT0723]]
[[07.24 Accepting Pipeline Data as a Block|PT0724]]
[[07.25 Using Pipeline Filters|PT0725]]
[[07.26 Determine Functions Pipeline Position|PT0726]]
[[07.27 Adding Write Protection to Functions|PT0727]]
[[07.28 Spying On Functions and Viewing Source Code|PT0728]]
[[07.29 Using Common Parameters|PT0729]]
[[07.30 Using Risk Mitigation Parameters|PT0730]]
[[07.31 Using Custom Risk Mitigation Code|PT0731]]
[[07.32 Adding Rich Help|PT0732]]
[[08.01 Static .NET Methods|PT0801]]
[[08.02 Getting Documentation|PT0802]]
[[08.03 Listing Static Members|PT0803]]
[[08.04 Converting Types|PT0804]]
[[08.05 Turning On Standby-Mode|PT0805]]
[[08.06 Listing Available Culture IDs|PT0806]]
[[08.07 Testing Numbers and Date|PT0807]]
[[08.08 Get Localized Month Names|PT0808]]
[[08.09 Listing Internet Explorer Cookies|PT0809]]
[[08.10 Counting Special Characters|PT0810]]
[[08.11 Getting Time Zones|PT0811]]
[[08.12 Getting Character Ranges|PT0812]]
[[08.13 Check for Wildcards|PT0813]]
[[08.14 Get-Clipboard|PT0814]]
[[08.15 Set-Clipboard|PT0815]]
[[08.16 Playing Sound in PowerShell|PT0816]]
[[08.17 Finding Days in Month|PT0817]]
[[08.18 Finding Leap Years|PT0818]]
[[08.19 Resolve Host Names|PT0819]]
[[08.20 Renewing All DHCP Leases|PT0820]]
[[08.21 Defining Return Values|PT0821]]
[[08.22 Secret TimeSpan Shortcuts|PT0822]]
[[08.23 Creating Relative Dates|PT0823]]
[[08.24 Test Internet Connection|PT0824]]
[[08.25 Finding Multiple RegEx Patterns|PT0825]]
[[08.26 Translating Culture IDs to Country Names|PT0826]]
[[08.27 Escape Regular Expressions|PT0827]]
[[08.28 Extracting Icons|PT0828]]
[[08.29 Getting SID of the Current User|PT0829]]
[[08.30 Test Admin Privileges|PT0830]]
[[08.31 Setting Mouse Position|PT0831]]
[[08.32 Converting Date to WMI Date|PT0832]]
[[08.33 Finding Built-In Cmdlets|PT0833]]
[[08.34 Check for 64-Bit Environment|PT0834]]
[[08.35 Converting Bitmaps to Icons|PT0835]]
[[08.36 Showing MsgBox|PT0836]]
[[08.37 ASCII Table|PT0837]]
[[08.38 Check for Numeric Characters|PT0838]]
[[08.39 Getting Significant Bytes|PT0839]]
[[08.40 Permanent Changes to Environment Variables|PT0840]]
[[08.41 Strongly-Typed Variables|PT0841]]
[[08.42 Finding System Folders|PT0842]]
[[08.43 Open File Exclusively|PT0843]]
[[08.44 Removing File Extensions|PT0844]]
[[08.45 Quickly Changing File Extensions|PT0845]]
[[08.46 Identifying 64-Bit Environments|PT0846]]
[[09.01 Accessing Registry|PT0901]]
[[09.02 Reading Registry Hives|PT0902]]
[[09.03 Using Native Registry Paths|PT0903]]
[[09.04 Reading Registry Values|PT0904]]
[[09.05 Reading Default Values|PT0905]]
[[09.06 Creating New Registry Keys|PT0906]]
[[09.07 Creating or Changing Registry Values|PT0907]]
[[09.08 Creating Registry Values with Type|PT0908]]
[[09.09 Remove Registry Keys and Values|PT0909]]
[[09.10 Listing Installed Software|PT0910]]
[[09.11 Test Whether Registry Key Exists|PT0911]]
[[09.12 Test Whether Registry Value Exists|PT0912]]
[[09.13 Exclude Unwanted Registry Values|PT0913]]
[[09.14 Accessing Registry Remotely|PT0914]]
[[09.15 List Registry Hives|PT0915]]
[[09.16 Load Registry User Hive|PT0916]]
[[09.17 Copy Registry Hives|PT0917]]
[[09.18 Scanning Registry for ClassIDs|PT0918]]
[[09.19 Enumerating Registry Keys with Style|PT0919]]
[[09.20 Getting Windows Product Key|PT0920]]
[[09.21 Investigating USB Drive Usage|PT0921]]
[[10.01 Downloading Files|PT1001]]
[[10.02 Get WebClient with Proxy Authentication|PT1002]]
[[10.03 Downloads with Progress Bar|PT1003]]
[[10.04 Resolving Redirects|PT1004]]
[[10.05 Downloading with BitsTransfer|PT1005]]
[[10.06 Asynchronous Downloads with BITS|PT1006]]
[[10.07 Downloading with Invoke-WebRequest|PT1007]]
[[10.09 Unblocking Downloaded Files|PT1009]]
[[10.10 Download Web Page Content|PT1010]]
[[10.11 Ripping All Links from a Website|PT1011]]
[[10.12 Scraping Information from Blogs and Web Pages|PT1012]]
[[10.13 Getting RSS Feed Information|PT1013]]
[[10.14 Getting Up-to-Date Exchange Rates|PT1014]]
[[10.15 Finding Popular Historic First Names|PT1015]]
[[10.16 Search and View PowerShell Videos|PT1016]]
[[10.17 Getting Most Recent Earthquakes|PT1017]]
[[10.18 Getting Excuses Automatically|PT1018]]
[[10.19 Validating a URL|PT1019]]
[[10.20 Analyzing URLs|PT1020]]
[[10.21 URL Encoding and Decoding|PT1021]]
[[10.23 HTML Encoding and Decoding|PT1023]]
[[10.24 Accessing Internet Explorer|PT1024]]
[[10.25 Testing Open Browser Windows|PT1025]]
[[10.26 Sending POST Data via PowerShell|PT1026]]
[[10.27 Refreshing Web Pages|PT1027]]
[[10.28 Testing URLs for Proxy Bypass|PT1028]]
[[11.01 XML-Related Cmdlets|PT1101]]
[[11.02 XPath|PT1102]]
[[11.03 Creating New XML Files Manually|PT1103]]
[[11.04 Creating New XML Files Programmatically|PT1104]]
[[11.05 Loading RSS Feeds and other Internet Data|PT1105]]
[[11.06 Accessing Internet XML Data through Proxy|PT1106]]
[[11.07 Selecting XML Data|PT1107]]
[[11.09 Using XPath to Search for XML Nodes|PT1109]]
[[11.10 Using XPath to Search for Attributes|PT1110]]
[[11.11 Using Advanced Searches|PT1111]]
[[11.12 Mastering Case-Sensitivity|PT1112]]
[[11.13 Changing XML Data|PT1113]]
[[11.14 Changing Multiple Instances of XML Data|PT1114]]
[[11.15 Appending New Data to Existing XML|PT1115]]
[[11.16 Removing XML Data|PT1116]]
[[11.17 Persisting Objects with XML|PT1117]]
[[11.18 Finding Type Definitions Using XPath|PT1118]]
[[11.19 Formatting XML Files|PT1119]]
[[11.20 Output Scheduled Tasks to XML|PT1120]]
[[11.21 Creating Scheduled Tasks from XML|PT1121]]
[[11.23 Getting Weather Forecast from an Airfield near You|PT1123]]
[[11.24 Searching Object Properties|PT1124]]
[[11.25 Adding Custom Methods to Types|PT1125]]
[[12.01 Understanding Execution Policy |PT1201]]
[[12.02 Overriding Execution Policy |PT1202]]
[[12.03 Listing NTFS Permissions |PT1203]]
[[12.04 Reading Security Descriptors in SDDL Form |PT1204]]
[[12.05 Clone NTFS Permissions |PT1205]]
[[12.06 Adding Permissions |PT1206]]
[[12.07 Removing Permissions |PT1207]]
[[12.08 Checking Administrator Privileges |PT1208]]
[[12.09 Show Admin Status in Prompt |PT1209]]
[[12.10 Waiting for Elevated Processes |PT1210]]
[[12.11 Executing Elevated PowerShell Code |PT1211]]
[[12.12 Requiring Administrator Privileges |PT1212]]
[[12.13 Automatically Elevating Script |PT1213]]
[[12.14 Asking for Credentials |PT1214]]
[[12.15 Finding Expired Certificates |PT1215]]
[[12.16 Deleting Installed Certificates |PT1216]]
[[12.17 Turning User Names into SIDs |PT1217]]
[[12.18 Turning SIDs into Real Names |PT1218]]
[[12.19 Finding Profiles |PT1219]]
[[12.20 Finding Security Info for the Current User |PT1220]]
[[12.21 Finding Current Group Memberships |PT1221]]
[[12.22 Generate Random Passwords |PT1222]]
[[12.23 Encrypt Files with EFS |PT1223]]
[[12.24 Entering Passwords Securely |PT1224]]
[[12.25 Decrypting SecureStrings |PT1225]]
[[12.26 Unattended Authentication|PT1226]]
{{{
# Turn display off by calling WindowsAPI.
# SendMessage(HWND_BROADCAST,WM_SYSCOMMAND, SC_MONITORPOWER, POWER_OFF)
# HWND_BROADCAST  0xffff
# WM_SYSCOMMAND   0x0112
# SC_MONITORPOWER 0xf170
# POWER_OFF       0x0002

Add-Type -TypeDefinition '
using System;
using System.Runtime.InteropServices;
 
namespace PVL {
   public static partial class WindowsAPI 
   {
      [DllImport("user32.dll", CharSet = CharSet.Auto)]
	   public static extern IntPtr PostMessage(
         IntPtr hWnd,
         UInt32 Msg,
         IntPtr wParam,
         IntPtr lParam
      );
   }

   public static partial class Utility
   {
   public static partial class Display
   {
      public static void DisplayOff()
      {
         WindowsAPI.PostMessage(
            (IntPtr)0xffff, 0x0112, (IntPtr)0xf170, (IntPtr)0x0002 );
      }
   }
   }
}
'

function Set-DisplayOff{
   [PVL.Utility+Display]::DisplayOff();
}
[PVL.Utility+Display]::DisplayOff();

}}}
/***
Description: Contains the stuff you need to use Tiddlyspot
Note, you also need UploadPlugin, PasswordOptionPlugin and LoadRemoteFileThroughProxy
from http://tiddlywiki.bidix.info for a complete working Tiddlyspot site.
***/
//{{{

// edit this if you are migrating sites or retrofitting an existing TW
config.tiddlyspotSiteId = 'spowershell';

// make it so you can by default see edit controls via http
config.options.chkHttpReadOnly = false;
window.readOnly = false; // make sure of it (for tw 2.2)
window.showBackstage = true; // show backstage too

// disable autosave in d3
if (window.location.protocol != "file:")
	config.options.chkGTDLazyAutoSave = false;

// tweak shadow tiddlers to add upload button, password entry box etc
with (config.shadowTiddlers) {
	SiteUrl = 'http://'+config.tiddlyspotSiteId+'.tiddlyspot.com';
	SideBarOptions = SideBarOptions.replace(/(<<saveChanges>>)/,"$1<<tiddler TspotSidebar>>");
	OptionsPanel = OptionsPanel.replace(/^/,"<<tiddler TspotOptions>>");
	DefaultTiddlers = DefaultTiddlers.replace(/^/,"[[WelcomeToTiddlyspot]] ");
	MainMenu = MainMenu.replace(/^/,"[[WelcomeToTiddlyspot]] ");
}

// create some shadow tiddler content
merge(config.shadowTiddlers,{

'TspotControls':[
 "| tiddlyspot password:|<<option pasUploadPassword>>|",
 "| site management:|<<upload http://" + config.tiddlyspotSiteId + ".tiddlyspot.com/store.cgi index.html . .  " + config.tiddlyspotSiteId + ">>//(requires tiddlyspot password)//<br>[[control panel|http://" + config.tiddlyspotSiteId + ".tiddlyspot.com/controlpanel]], [[download (go offline)|http://" + config.tiddlyspotSiteId + ".tiddlyspot.com/download]]|",
 "| links:|[[tiddlyspot.com|http://tiddlyspot.com/]], [[FAQs|http://faq.tiddlyspot.com/]], [[blog|http://tiddlyspot.blogspot.com/]], email [[support|mailto:support@tiddlyspot.com]] & [[feedback|mailto:feedback@tiddlyspot.com]], [[donate|http://tiddlyspot.com/?page=donate]]|"
].join("\n"),

'TspotOptions':[
 "tiddlyspot password:",
 "<<option pasUploadPassword>>",
 ""
].join("\n"),

'TspotSidebar':[
 "<<upload http://" + config.tiddlyspotSiteId + ".tiddlyspot.com/store.cgi index.html . .  " + config.tiddlyspotSiteId + ">><html><a href='http://" + config.tiddlyspotSiteId + ".tiddlyspot.com/download' class='button'>download</a></html>"
].join("\n"),

'WelcomeToTiddlyspot':[
 "This document is a ~TiddlyWiki from tiddlyspot.com.  A ~TiddlyWiki is an electronic notebook that is great for managing todo lists, personal information, and all sorts of things.",
 "",
 "@@font-weight:bold;font-size:1.3em;color:#444; //What now?// &nbsp;&nbsp;@@ Before you can save any changes, you need to enter your password in the form below.  Then configure privacy and other site settings at your [[control panel|http://" + config.tiddlyspotSiteId + ".tiddlyspot.com/controlpanel]] (your control panel username is //" + config.tiddlyspotSiteId + "//).",
 "<<tiddler TspotControls>>",
 "See also GettingStarted.",
 "",
 "@@font-weight:bold;font-size:1.3em;color:#444; //Working online// &nbsp;&nbsp;@@ You can edit this ~TiddlyWiki right now, and save your changes using the \"save to web\" button in the column on the right.",
 "",
 "@@font-weight:bold;font-size:1.3em;color:#444; //Working offline// &nbsp;&nbsp;@@ A fully functioning copy of this ~TiddlyWiki can be saved onto your hard drive or USB stick.  You can make changes and save them locally without being connected to the Internet.  When you're ready to sync up again, just click \"upload\" and your ~TiddlyWiki will be saved back to tiddlyspot.com.",
 "",
 "@@font-weight:bold;font-size:1.3em;color:#444; //Help!// &nbsp;&nbsp;@@ Find out more about ~TiddlyWiki at [[TiddlyWiki.com|http://tiddlywiki.com]].  Also visit [[TiddlyWiki.org|http://tiddlywiki.org]] for documentation on learning and using ~TiddlyWiki. New users are especially welcome on the [[TiddlyWiki mailing list|http://groups.google.com/group/TiddlyWiki]], which is an excellent place to ask questions and get help.  If you have a tiddlyspot related problem email [[tiddlyspot support|mailto:support@tiddlyspot.com]].",
 "",
 "@@font-weight:bold;font-size:1.3em;color:#444; //Enjoy :)// &nbsp;&nbsp;@@ We hope you like using your tiddlyspot.com site.  Please email [[feedback@tiddlyspot.com|mailto:feedback@tiddlyspot.com]] with any comments or suggestions."
].join("\n")

});
//}}}
| !date | !user | !location | !storeUrl | !uploadDir | !toFilename | !backupdir | !origin |
| 12/02/2016 02:01:02 | Sara | [[/|http://spowershell.tiddlyspot.com/]] | [[store.cgi|http://spowershell.tiddlyspot.com/store.cgi]] | . | [[index.html | http://spowershell.tiddlyspot.com/index.html]] | . |
| 14/02/2016 06:36:23 | Sara | [[/|http://spowershell.tiddlyspot.com/]] | [[store.cgi|http://spowershell.tiddlyspot.com/store.cgi]] | . | [[index.html | http://spowershell.tiddlyspot.com/index.html]] | . |
| 18/02/2016 00:25:09 | Sara | [[/|http://spowershell.tiddlyspot.com/]] | [[store.cgi|http://spowershell.tiddlyspot.com/store.cgi]] | . | [[index.html | http://spowershell.tiddlyspot.com/index.html]] | . |
| 10/03/2016 01:33:37 | Sara | [[/|http://spowershell.tiddlyspot.com/]] | [[store.cgi|http://spowershell.tiddlyspot.com/store.cgi]] | . | [[index.html | http://spowershell.tiddlyspot.com/index.html]] | . | ok |
| 10/03/2016 01:36:42 | Sara | [[/|http://spowershell.tiddlyspot.com/]] | [[store.cgi|http://spowershell.tiddlyspot.com/store.cgi]] | . | [[index.html | http://spowershell.tiddlyspot.com/index.html]] | . |
| 04/04/2016 01:28:08 | Sara | [[/|http://spowershell.tiddlyspot.com/]] | [[store.cgi|http://spowershell.tiddlyspot.com/store.cgi]] | . | [[index.html | http://spowershell.tiddlyspot.com/index.html]] | . |
| 16/04/2016 23:42:52 | Sara | [[/|http://spowershell.tiddlyspot.com/]] | [[store.cgi|http://spowershell.tiddlyspot.com/store.cgi]] | . | [[index.html | http://spowershell.tiddlyspot.com/index.html]] | . |
| 24/04/2016 01:03:31 | Sara | [[/|http://spowershell.tiddlyspot.com/]] | [[store.cgi|http://spowershell.tiddlyspot.com/store.cgi]] | . | [[index.html | http://spowershell.tiddlyspot.com/index.html]] | . | ok |
| 24/04/2016 01:07:43 | Sara | [[/|http://spowershell.tiddlyspot.com/]] | [[store.cgi|http://spowershell.tiddlyspot.com/store.cgi]] | . | [[index.html | http://spowershell.tiddlyspot.com/index.html]] | . | ok |
| 24/04/2016 01:08:00 | Sara | [[/|http://spowershell.tiddlyspot.com/]] | [[store.cgi|http://spowershell.tiddlyspot.com/store.cgi]] | . | [[index.html | http://spowershell.tiddlyspot.com/index.html]] | . |
/***
|''Name:''|UploadPlugin|
|''Description:''|Save to web a TiddlyWiki|
|''Version:''|4.1.3|
|''Date:''|Feb 24, 2008|
|''Source:''|http://tiddlywiki.bidix.info/#UploadPlugin|
|''Documentation:''|http://tiddlywiki.bidix.info/#UploadPluginDoc|
|''Author:''|BidiX (BidiX (at) bidix (dot) info)|
|''License:''|[[BSD open source license|http://tiddlywiki.bidix.info/#%5B%5BBSD%20open%20source%20license%5D%5D ]]|
|''~CoreVersion:''|2.2.0|
|''Requires:''|PasswordOptionPlugin|
***/
//{{{
version.extensions.UploadPlugin = {
	major: 4, minor: 1, revision: 3,
	date: new Date("Feb 24, 2008"),
	source: 'http://tiddlywiki.bidix.info/#UploadPlugin',
	author: 'BidiX (BidiX (at) bidix (dot) info',
	coreVersion: '2.2.0'
};

//
// Environment
//

if (!window.bidix) window.bidix = {}; // bidix namespace
bidix.debugMode = false;	// true to activate both in Plugin and UploadService
	
//
// Upload Macro
//

config.macros.upload = {
// default values
	defaultBackupDir: '',	//no backup
	defaultStoreScript: "store.php",
	defaultToFilename: "index.html",
	defaultUploadDir: ".",
	authenticateUser: true	// UploadService Authenticate User
};
	
config.macros.upload.label = {
	promptOption: "Save and Upload this TiddlyWiki with UploadOptions",
	promptParamMacro: "Save and Upload this TiddlyWiki in %0",
	saveLabel: "save to web", 
	saveToDisk: "save to disk",
	uploadLabel: "upload"	
};

config.macros.upload.messages = {
	noStoreUrl: "No store URL in parmeters or options",
	usernameOrPasswordMissing: "Username or password missing"
};

config.macros.upload.handler = function(place,macroName,params) {
	if (readOnly)
		return;
	var label;
	if (document.location.toString().substr(0,4) == "http") 
		label = this.label.saveLabel;
	else
		label = this.label.uploadLabel;
	var prompt;
	if (params[0]) {
		prompt = this.label.promptParamMacro.toString().format([this.destFile(params[0], 
			(params[1] ? params[1]:bidix.basename(window.location.toString())), params[3])]);
	} else {
		prompt = this.label.promptOption;
	}
	createTiddlyButton(place, label, prompt, function() {config.macros.upload.action(params);}, null, null, this.accessKey);
};

config.macros.upload.action = function(params)
{
		// for missing macro parameter set value from options
		if (!params) params = {};
		var storeUrl = params[0] ? params[0] : config.options.txtUploadStoreUrl;
		var toFilename = params[1] ? params[1] : config.options.txtUploadFilename;
		var backupDir = params[2] ? params[2] : config.options.txtUploadBackupDir;
		var uploadDir = params[3] ? params[3] : config.options.txtUploadDir;
		var username = params[4] ? params[4] : config.options.txtUploadUserName;
		var password = config.options.pasUploadPassword; // for security reason no password as macro parameter	
		// for still missing parameter set default value
		if ((!storeUrl) && (document.location.toString().substr(0,4) == "http")) 
			storeUrl = bidix.dirname(document.location.toString())+'/'+config.macros.upload.defaultStoreScript;
		if (storeUrl.substr(0,4) != "http")
			storeUrl = bidix.dirname(document.location.toString()) +'/'+ storeUrl;
		if (!toFilename)
			toFilename = bidix.basename(window.location.toString());
		if (!toFilename)
			toFilename = config.macros.upload.defaultToFilename;
		if (!uploadDir)
			uploadDir = config.macros.upload.defaultUploadDir;
		if (!backupDir)
			backupDir = config.macros.upload.defaultBackupDir;
		// report error if still missing
		if (!storeUrl) {
			alert(config.macros.upload.messages.noStoreUrl);
			clearMessage();
			return false;
		}
		if (config.macros.upload.authenticateUser && (!username || !password)) {
			alert(config.macros.upload.messages.usernameOrPasswordMissing);
			clearMessage();
			return false;
		}
		bidix.upload.uploadChanges(false,null,storeUrl, toFilename, uploadDir, backupDir, username, password); 
		return false; 
};

config.macros.upload.destFile = function(storeUrl, toFilename, uploadDir) 
{
	if (!storeUrl)
		return null;
		var dest = bidix.dirname(storeUrl);
		if (uploadDir && uploadDir != '.')
			dest = dest + '/' + uploadDir;
		dest = dest + '/' + toFilename;
	return dest;
};

//
// uploadOptions Macro
//

config.macros.uploadOptions = {
	handler: function(place,macroName,params) {
		var wizard = new Wizard();
		wizard.createWizard(place,this.wizardTitle);
		wizard.addStep(this.step1Title,this.step1Html);
		var markList = wizard.getElement("markList");
		var listWrapper = document.createElement("div");
		markList.parentNode.insertBefore(listWrapper,markList);
		wizard.setValue("listWrapper",listWrapper);
		this.refreshOptions(listWrapper,false);
		var uploadCaption;
		if (document.location.toString().substr(0,4) == "http") 
			uploadCaption = config.macros.upload.label.saveLabel;
		else
			uploadCaption = config.macros.upload.label.uploadLabel;
		
		wizard.setButtons([
				{caption: uploadCaption, tooltip: config.macros.upload.label.promptOption, 
					onClick: config.macros.upload.action},
				{caption: this.cancelButton, tooltip: this.cancelButtonPrompt, onClick: this.onCancel}
				
			]);
	},
	options: [
		"txtUploadUserName",
		"pasUploadPassword",
		"txtUploadStoreUrl",
		"txtUploadDir",
		"txtUploadFilename",
		"txtUploadBackupDir",
		"chkUploadLog",
		"txtUploadLogMaxLine"		
	],
	refreshOptions: function(listWrapper) {
		var opts = [];
		for(i=0; i<this.options.length; i++) {
			var opt = {};
			opts.push();
			opt.option = "";
			n = this.options[i];
			opt.name = n;
			opt.lowlight = !config.optionsDesc[n];
			opt.description = opt.lowlight ? this.unknownDescription : config.optionsDesc[n];
			opts.push(opt);
		}
		var listview = ListView.create(listWrapper,opts,this.listViewTemplate);
		for(n=0; n<opts.length; n++) {
			var type = opts[n].name.substr(0,3);
			var h = config.macros.option.types[type];
			if (h && h.create) {
				h.create(opts[n].colElements['option'],type,opts[n].name,opts[n].name,"no");
			}
		}
		
	},
	onCancel: function(e)
	{
		backstage.switchTab(null);
		return false;
	},
	
	wizardTitle: "Upload with options",
	step1Title: "These options are saved in cookies in your browser",
	step1Html: "<input type='hidden' name='markList'></input><br>",
	cancelButton: "Cancel",
	cancelButtonPrompt: "Cancel prompt",
	listViewTemplate: {
		columns: [
			{name: 'Description', field: 'description', title: "Description", type: 'WikiText'},
			{name: 'Option', field: 'option', title: "Option", type: 'String'},
			{name: 'Name', field: 'name', title: "Name", type: 'String'}
			],
		rowClasses: [
			{className: 'lowlight', field: 'lowlight'} 
			]}
};

//
// upload functions
//

if (!bidix.upload) bidix.upload = {};

if (!bidix.upload.messages) bidix.upload.messages = {
	//from saving
	invalidFileError: "The original file '%0' does not appear to be a valid TiddlyWiki",
	backupSaved: "Backup saved",
	backupFailed: "Failed to upload backup file",
	rssSaved: "RSS feed uploaded",
	rssFailed: "Failed to upload RSS feed file",
	emptySaved: "Empty template uploaded",
	emptyFailed: "Failed to upload empty template file",
	mainSaved: "Main TiddlyWiki file uploaded",
	mainFailed: "Failed to upload main TiddlyWiki file. Your changes have not been saved",
	//specific upload
	loadOriginalHttpPostError: "Can't get original file",
	aboutToSaveOnHttpPost: 'About to upload on %0 ...',
	storePhpNotFound: "The store script '%0' was not found."
};

bidix.upload.uploadChanges = function(onlyIfDirty,tiddlers,storeUrl,toFilename,uploadDir,backupDir,username,password)
{
	var callback = function(status,uploadParams,original,url,xhr) {
		if (!status) {
			displayMessage(bidix.upload.messages.loadOriginalHttpPostError);
			return;
		}
		if (bidix.debugMode) 
			alert(original.substr(0,500)+"\n...");
		// Locate the storeArea div's 
		var posDiv = locateStoreArea(original);
		if((posDiv[0] == -1) || (posDiv[1] == -1)) {
			alert(config.messages.invalidFileError.format([localPath]));
			return;
		}
		bidix.upload.uploadRss(uploadParams,original,posDiv);
	};
	
	if(onlyIfDirty && !store.isDirty())
		return;
	clearMessage();
	// save on localdisk ?
	if (document.location.toString().substr(0,4) == "file") {
		var path = document.location.toString();
		var localPath = getLocalPath(path);
		saveChanges();
	}
	// get original
	var uploadParams = new Array(storeUrl,toFilename,uploadDir,backupDir,username,password);
	var originalPath = document.location.toString();
	// If url is a directory : add index.html
	if (originalPath.charAt(originalPath.length-1) == "/")
		originalPath = originalPath + "index.html";
	var dest = config.macros.upload.destFile(storeUrl,toFilename,uploadDir);
	var log = new bidix.UploadLog();
	log.startUpload(storeUrl, dest, uploadDir,  backupDir);
	displayMessage(bidix.upload.messages.aboutToSaveOnHttpPost.format([dest]));
	if (bidix.debugMode) 
		alert("about to execute Http - GET on "+originalPath);
	var r = doHttp("GET",originalPath,null,null,username,password,callback,uploadParams,null);
	if (typeof r == "string")
		displayMessage(r);
	return r;
};

bidix.upload.uploadRss = function(uploadParams,original,posDiv) 
{
	var callback = function(status,params,responseText,url,xhr) {
		if(status) {
			var destfile = responseText.substring(responseText.indexOf("destfile:")+9,responseText.indexOf("\n", responseText.indexOf("destfile:")));
			displayMessage(bidix.upload.messages.rssSaved,bidix.dirname(url)+'/'+destfile);
			bidix.upload.uploadMain(params[0],params[1],params[2]);
		} else {
			displayMessage(bidix.upload.messages.rssFailed);			
		}
	};
	// do uploadRss
	if(config.options.chkGenerateAnRssFeed) {
		var rssPath = uploadParams[1].substr(0,uploadParams[1].lastIndexOf(".")) + ".xml";
		var rssUploadParams = new Array(uploadParams[0],rssPath,uploadParams[2],'',uploadParams[4],uploadParams[5]);
		var rssString = generateRss();
		// no UnicodeToUTF8 conversion needed when location is "file" !!!
		if (document.location.toString().substr(0,4) != "file")
			rssString = convertUnicodeToUTF8(rssString);	
		bidix.upload.httpUpload(rssUploadParams,rssString,callback,Array(uploadParams,original,posDiv));
	} else {
		bidix.upload.uploadMain(uploadParams,original,posDiv);
	}
};

bidix.upload.uploadMain = function(uploadParams,original,posDiv) 
{
	var callback = function(status,params,responseText,url,xhr) {
		var log = new bidix.UploadLog();
		if(status) {
			// if backupDir specified
			if ((params[3]) && (responseText.indexOf("backupfile:") > -1))  {
				var backupfile = responseText.substring(responseText.indexOf("backupfile:")+11,responseText.indexOf("\n", responseText.indexOf("backupfile:")));
				displayMessage(bidix.upload.messages.backupSaved,bidix.dirname(url)+'/'+backupfile);
			}
			var destfile = responseText.substring(responseText.indexOf("destfile:")+9,responseText.indexOf("\n", responseText.indexOf("destfile:")));
			displayMessage(bidix.upload.messages.mainSaved,bidix.dirname(url)+'/'+destfile);
			store.setDirty(false);
			log.endUpload("ok");
		} else {
			alert(bidix.upload.messages.mainFailed);
			displayMessage(bidix.upload.messages.mainFailed);
			log.endUpload("failed");			
		}
	};
	// do uploadMain
	var revised = bidix.upload.updateOriginal(original,posDiv);
	bidix.upload.httpUpload(uploadParams,revised,callback,uploadParams);
};

bidix.upload.httpUpload = function(uploadParams,data,callback,params)
{
	var localCallback = function(status,params,responseText,url,xhr) {
		url = (url.indexOf("nocache=") < 0 ? url : url.substring(0,url.indexOf("nocache=")-1));
		if (xhr.status == 404)
			alert(bidix.upload.messages.storePhpNotFound.format([url]));
		if ((bidix.debugMode) || (responseText.indexOf("Debug mode") >= 0 )) {
			alert(responseText);
			if (responseText.indexOf("Debug mode") >= 0 )
				responseText = responseText.substring(responseText.indexOf("\n\n")+2);
		} else if (responseText.charAt(0) != '0') 
			alert(responseText);
		if (responseText.charAt(0) != '0')
			status = null;
		callback(status,params,responseText,url,xhr);
	};
	// do httpUpload
	var boundary = "---------------------------"+"AaB03x";	
	var uploadFormName = "UploadPlugin";
	// compose headers data
	var sheader = "";
	sheader += "--" + boundary + "\r\nContent-disposition: form-data; name=\"";
	sheader += uploadFormName +"\"\r\n\r\n";
	sheader += "backupDir="+uploadParams[3] +
				";user=" + uploadParams[4] +
				";password=" + uploadParams[5] +
				";uploaddir=" + uploadParams[2];
	if (bidix.debugMode)
		sheader += ";debug=1";
	sheader += ";;\r\n"; 
	sheader += "\r\n" + "--" + boundary + "\r\n";
	sheader += "Content-disposition: form-data; name=\"userfile\"; filename=\""+uploadParams[1]+"\"\r\n";
	sheader += "Content-Type: text/html;charset=UTF-8" + "\r\n";
	sheader += "Content-Length: " + data.length + "\r\n\r\n";
	// compose trailer data
	var strailer = new String();
	strailer = "\r\n--" + boundary + "--\r\n";
	data = sheader + data + strailer;
	if (bidix.debugMode) alert("about to execute Http - POST on "+uploadParams[0]+"\n with \n"+data.substr(0,500)+ " ... ");
	var r = doHttp("POST",uploadParams[0],data,"multipart/form-data; ;charset=UTF-8; boundary="+boundary,uploadParams[4],uploadParams[5],localCallback,params,null);
	if (typeof r == "string")
		displayMessage(r);
	return r;
};

// same as Saving's updateOriginal but without convertUnicodeToUTF8 calls
bidix.upload.updateOriginal = function(original, posDiv)
{
	if (!posDiv)
		posDiv = locateStoreArea(original);
	if((posDiv[0] == -1) || (posDiv[1] == -1)) {
		alert(config.messages.invalidFileError.format([localPath]));
		return;
	}
	var revised = original.substr(0,posDiv[0] + startSaveArea.length) + "\n" +
				store.allTiddlersAsHtml() + "\n" +
				original.substr(posDiv[1]);
	var newSiteTitle = getPageTitle().htmlEncode();
	revised = revised.replaceChunk("<title"+">","</title"+">"," " + newSiteTitle + " ");
	revised = updateMarkupBlock(revised,"PRE-HEAD","MarkupPreHead");
	revised = updateMarkupBlock(revised,"POST-HEAD","MarkupPostHead");
	revised = updateMarkupBlock(revised,"PRE-BODY","MarkupPreBody");
	revised = updateMarkupBlock(revised,"POST-SCRIPT","MarkupPostBody");
	return revised;
};

//
// UploadLog
// 
// config.options.chkUploadLog :
//		false : no logging
//		true : logging
// config.options.txtUploadLogMaxLine :
//		-1 : no limit
//      0 :  no Log lines but UploadLog is still in place
//		n :  the last n lines are only kept
//		NaN : no limit (-1)

bidix.UploadLog = function() {
	if (!config.options.chkUploadLog) 
		return; // this.tiddler = null
	this.tiddler = store.getTiddler("UploadLog");
	if (!this.tiddler) {
		this.tiddler = new Tiddler();
		this.tiddler.title = "UploadLog";
		this.tiddler.text = "| !date | !user | !location | !storeUrl | !uploadDir | !toFilename | !backupdir | !origin |";
		this.tiddler.created = new Date();
		this.tiddler.modifier = config.options.txtUserName;
		this.tiddler.modified = new Date();
		store.addTiddler(this.tiddler);
	}
	return this;
};

bidix.UploadLog.prototype.addText = function(text) {
	if (!this.tiddler)
		return;
	// retrieve maxLine when we need it
	var maxLine = parseInt(config.options.txtUploadLogMaxLine,10);
	if (isNaN(maxLine))
		maxLine = -1;
	// add text
	if (maxLine != 0) 
		this.tiddler.text = this.tiddler.text + text;
	// Trunck to maxLine
	if (maxLine >= 0) {
		var textArray = this.tiddler.text.split('\n');
		if (textArray.length > maxLine + 1)
			textArray.splice(1,textArray.length-1-maxLine);
			this.tiddler.text = textArray.join('\n');		
	}
	// update tiddler fields
	this.tiddler.modifier = config.options.txtUserName;
	this.tiddler.modified = new Date();
	store.addTiddler(this.tiddler);
	// refresh and notifiy for immediate update
	story.refreshTiddler(this.tiddler.title);
	store.notify(this.tiddler.title, true);
};

bidix.UploadLog.prototype.startUpload = function(storeUrl, toFilename, uploadDir,  backupDir) {
	if (!this.tiddler)
		return;
	var now = new Date();
	var text = "\n| ";
	var filename = bidix.basename(document.location.toString());
	if (!filename) filename = '/';
	text += now.formatString("0DD/0MM/YYYY 0hh:0mm:0ss") +" | ";
	text += config.options.txtUserName + " | ";
	text += "[["+filename+"|"+location + "]] |";
	text += " [[" + bidix.basename(storeUrl) + "|" + storeUrl + "]] | ";
	text += uploadDir + " | ";
	text += "[[" + bidix.basename(toFilename) + " | " +toFilename + "]] | ";
	text += backupDir + " |";
	this.addText(text);
};

bidix.UploadLog.prototype.endUpload = function(status) {
	if (!this.tiddler)
		return;
	this.addText(" "+status+" |");
};

//
// Utilities
// 

bidix.checkPlugin = function(plugin, major, minor, revision) {
	var ext = version.extensions[plugin];
	if (!
		(ext  && 
			((ext.major > major) || 
			((ext.major == major) && (ext.minor > minor))  ||
			((ext.major == major) && (ext.minor == minor) && (ext.revision >= revision))))) {
			// write error in PluginManager
			if (pluginInfo)
				pluginInfo.log.push("Requires " + plugin + " " + major + "." + minor + "." + revision);
			eval(plugin); // generate an error : "Error: ReferenceError: xxxx is not defined"
	}
};

bidix.dirname = function(filePath) {
	if (!filePath) 
		return;
	var lastpos;
	if ((lastpos = filePath.lastIndexOf("/")) != -1) {
		return filePath.substring(0, lastpos);
	} else {
		return filePath.substring(0, filePath.lastIndexOf("\\"));
	}
};

bidix.basename = function(filePath) {
	if (!filePath) 
		return;
	var lastpos;
	if ((lastpos = filePath.lastIndexOf("#")) != -1) 
		filePath = filePath.substring(0, lastpos);
	if ((lastpos = filePath.lastIndexOf("/")) != -1) {
		return filePath.substring(lastpos + 1);
	} else
		return filePath.substring(filePath.lastIndexOf("\\")+1);
};

bidix.initOption = function(name,value) {
	if (!config.options[name])
		config.options[name] = value;
};

//
// Initializations
//

// require PasswordOptionPlugin 1.0.1 or better
bidix.checkPlugin("PasswordOptionPlugin", 1, 0, 1);

// styleSheet
setStylesheet('.txtUploadStoreUrl, .txtUploadBackupDir, .txtUploadDir {width: 22em;}',"uploadPluginStyles");

//optionsDesc
merge(config.optionsDesc,{
	txtUploadStoreUrl: "Url of the UploadService script (default: store.php)",
	txtUploadFilename: "Filename of the uploaded file (default: in index.html)",
	txtUploadDir: "Relative Directory where to store the file (default: . (downloadService directory))",
	txtUploadBackupDir: "Relative Directory where to backup the file. If empty no backup. (default: ''(empty))",
	txtUploadUserName: "Upload Username",
	pasUploadPassword: "Upload Password",
	chkUploadLog: "do Logging in UploadLog (default: true)",
	txtUploadLogMaxLine: "Maximum of lines in UploadLog (default: 10)"
});

// Options Initializations
bidix.initOption('txtUploadStoreUrl','');
bidix.initOption('txtUploadFilename','');
bidix.initOption('txtUploadDir','');
bidix.initOption('txtUploadBackupDir','');
bidix.initOption('txtUploadUserName','');
bidix.initOption('pasUploadPassword','');
bidix.initOption('chkUploadLog',true);
bidix.initOption('txtUploadLogMaxLine','10');


// Backstage
merge(config.tasks,{
	uploadOptions: {text: "upload", tooltip: "Change UploadOptions and Upload", content: '<<uploadOptions>>'}
});
config.backstageTasks.push("uploadOptions");


//}}}

{{{
# MOUSEEVENTF_MOVE 0x0001

Add-Type -TypeDefinition '
using System;
using System.Runtime.InteropServices;
 
namespace PVL {
   public static partial class WINAPI 
   {
         [DllImport("user32.dll")]
            public static extern void mouse_event(
         Int32 dwFlags, 
         Int32 dx, 
         Int32 dy, 
         Int32 dwData, 
         UIntPtr dwExtraInfo
         );
   }
   public static partial class Utility
   {
   public static partial class Display
   {
      public static void WakeUp()
      {
         WINAPI.mouse_event(
	 0x001, 0, -1, 0, UIntPtr.Zero);
      }
   }
   }
}
'

function WakeUp{
   [PVL.Utility+Display]::WakeUp();
}
[PVL.Utility+Display]::WakeUp();
}}}
powershell /ps/WakeUp.ps1
[[denial of service (DDoS) attacks using spoofed recursive DNS requests| https://www.us-cert.gov/sites/default/files/publications/DNS-recursion033006.pdf]]
{{{
[east]: PS C:\Users\administrator.SHAN\Documents> Get-Disk

Number Friendly Name                            OperationalStatus                    Total Size Partition Style
------ -------------                            -----------------                    ---------- ---------------
0      Microsoft Virtual Disk                   Online                                    30 GB GPT
1      Microsoft Virtual Disk                   Offline                                   10 GB RAW
2      Microsoft Virtual Disk                   Offline                                   10 GB RAW


[east]: PS C:\Users\administrator.SHAN\Documents> Initialize-Disk –Number 2
[east]: PS C:\Users\administrator.SHAN\Documents> Get-Disk –Number 2

Number Friendly Name                            OperationalStatus                    Total Size Partition Style
------ -------------                            -----------------                    ---------- ---------------
2      Microsoft Virtual Disk                   Online                                    10 GB GPT


[east]: PS C:\Users\administrator.SHAN\Documents> New-Partition -DiskNumber 2 -AssignDriveLetter -UseMaximumSize


   Disk Number: 2

PartitionNumber  DriveLetter Offset                                        Size Type
---------------  ----------- ------                                        ---- ----
2                E           34603008                                   9.97 GB Basic


[east]: PS C:\Users\administrator.SHAN\Documents> Format-Volume –DriveLetter E –FileSystem NTFS

Confirm
Are you sure you want to perform this action?
Warning, all data on the volume will be lost!
[Y] Yes  [A] Yes to All  [N] No  [L] No to All  [?] Help (default is "Y"): Y

DriveLetter       FileSystemLabel  FileSystem       DriveType        HealthStatus        SizeRemaining             Size
-----------       ---------------  ----------       ---------        ------------        -------------             ----
E                                  NTFS             Fixed            Healthy                   9.92 GB          9.97 GB


[east]: PS C:\Users\administrator.SHAN\Documents> Optimize-Volume –DriveLetter E
[east]: PS C:\Users\administrator.SHAN\Documents> Get-Volume –DriveLetter E

DriveLetter       FileSystemLabel  FileSystem       DriveType        HealthStatus        SizeRemaining             Size
-----------       ---------------  ----------       ---------        ------------        -------------             ----
E                                  NTFS             Fixed            Healthy                   9.92 GB          9.97 GB


[east]: PS C:\Users\administrator.SHAN\Documents> Repair-Volume –DriveLetter E
NoErrorsFound
[east]: PS C:\Users\administrator.SHAN\Documents>

[east]: PS C:\Users\administrator.SHAN\Documents> Set-Volume –DriveLetter E –NewFileSystemLabel "TenGB"
[east]: PS C:\Users\administrator.SHAN\Documents> Get-Volume –DriveLetter E

DriveLetter       FileSystemLabel  FileSystem       DriveType        HealthStatus        SizeRemaining             Size
-----------       ---------------  ----------       ---------        ------------        -------------             ----
E                 TenGB            NTFS             Fixed            Healthy                   9.92 GB          9.97 GB


}}}
Ref: http://www.tomsitpro.com/articles/powershell-for-storage,2-764.html
PS C:\WINDOWS\system32> Get-ADUser GlenJohn -Properties *

{{{
AccountExpirationDate                :
accountExpires                       : 9223372036854775807
AccountLockoutTime                   :
AccountNotDelegated                  : False
AllowReversiblePasswordEncryption    : False
AuthenticationPolicy                 : {}
AuthenticationPolicySilo             : {}
BadLogonCount                        : 0
badPasswordTime                      : 0
badPwdCount                          : 0
CannotChangePassword                 : False
CanonicalName                        : shan.local/Users/Glen John
Certificates                         : {}
City                                 :
CN                                   : Glen John
codePage                             : 0
Company                              :
CompoundIdentitySupported            : {}
Country                              :
countryCode                          : 0
Created                              : 30/12/2015 1:13:40 PM
createTimeStamp                      : 30/12/2015 1:13:40 PM
Deleted                              :
Department                           :
Description                          :
DisplayName                          : Glen John
DistinguishedName                    : CN=Glen John,CN=Users,DC=shan,DC=local
Division                             :
DoesNotRequirePreAuth                : False
dSCorePropagationData                : {1/01/1601 10:00:00 AM}
EmailAddress                         :
EmployeeID                           :
EmployeeNumber                       :
Enabled                              : True
Fax                                  :
GivenName                            : Glen
HomeDirectory                        :
HomedirRequired                      : False
HomeDrive                            :
HomePage                             :
HomePhone                            :
Initials                             :
instanceType                         : 4
isDeleted                            :
KerberosEncryptionType               : {}
LastBadPasswordAttempt               :
LastKnownParent                      :
lastLogoff                           : 0
lastLogon                            : 0
LastLogonDate                        :
LockedOut                            : False
logonCount                           : 0
LogonWorkstations                    :
Manager                              :
MemberOf                             : {}
MNSLogonAccount                      : False
MobilePhone                          :
Modified                             : 30/12/2015 1:13:43 PM
modifyTimeStamp                      : 30/12/2015 1:13:43 PM
msDS-User-Account-Control-Computed   : 0
Name                                 : Glen John
nTSecurityDescriptor                 : System.DirectoryServices.ActiveDirectorySecurity
ObjectCategory                       : CN=Person,CN=Schema,CN=Configuration,DC=shan,DC=local
ObjectClass                          : user
ObjectGUID                           : 704e48bd-0901-4b01-9805-ef874fa141a5
objectSid                            : S-1-5-21-3943950521-2127120831-1704551434-1113
Office                               :
OfficePhone                          :
Organization                         :
OtherName                            :
PasswordExpired                      : False
PasswordLastSet                      : 30/12/2015 1:13:42 PM
PasswordNeverExpires                 : True
PasswordNotRequired                  : False
POBox                                :
PostalCode                           :
PrimaryGroup                         : CN=Domain Users,CN=Users,DC=shan,DC=local
primaryGroupID                       : 513
PrincipalsAllowedToDelegateToAccount : {}
ProfilePath                          :
ProtectedFromAccidentalDeletion      : False
pwdLastSet                           : 130959188225192664
SamAccountName                       : GlenJohn
sAMAccountType                       : 805306368
ScriptPath                           :
sDRightsEffective                    : 15
ServicePrincipalNames                : {}
SID                                  : S-1-5-21-3943950521-2127120831-1704551434-1113
SIDHistory                           : {}
SmartcardLogonRequired               : False
sn                                   : John
State                                :
StreetAddress                        :
Surname                              : John
Title                                :
TrustedForDelegation                 : False
TrustedToAuthForDelegation           : False
UseDESKeyOnly                        : False
userAccountControl                   : 66048
userCertificate                      : {}
UserPrincipalName                    : GlenJohn@shan.local
uSNChanged                           : 20759
uSNCreated                           : 20754
whenChanged                          : 30/12/2015 1:13:43 PM
whenCreated                          : 30/12/2015 1:13:40 PM
}}}
[HQEDC.shan.local]: PS C:\> Get-Disk
{{{
Number Friendly Name                            OperationalStatus                    Total Size Partition Style
------ -------------                            -----------------                    ---------- ---------------
0      Microsoft Virtual Disk                   Online                                    30 GB GPT
}}}

[HQEDC.shan.local]: PS C:\> Get-PhysicalDisk | ft -auto
{{{
FriendlyName  CanPool OperationalStatus HealthStatus Usage        Size
------------  ------- ----------------- ------------ -----        ----
PhysicalDisk0 False   OK                Healthy      Auto-Select 30 GB
}}}
When I issued the command notepad I got the following error.
Invoked powershell in Windows10. 
@@ServerManager -- selected server HQEDC -- invoked Windows Powershell@@
{{{
[HQEDC]: PS C:\Users\Administrator\Documents> notepad
The remote pipeline has been stopped.
    + CategoryInfo          : ResourceUnavailable: (:) [], ParentContainsErrorRecordException
    + FullyQualifiedErrorId : System.Management.Automation.Remoting.PSRemotingDataStructureException
}}}
wmic nicconfig get Description,SettingID
[[CONFIGURING WINDOWS SERVER 2012 CORE: POWERSHELL|http://www.florisvanderploeg.com/configuring-windows-server-2012-core-powershell/]]

http://stackoverflow.com/questions/6217799/rename-computer-and-join-to-domain-in-one-step-with-powershell

http://blogs.msdn.com/b/virtual_pc_guy/archive/2013/05/13/rename-the-guest-os-to-match-the-virtual-machine-name-on-hyper-v.aspx
https://www.vmguru.com/2015/11/powershell-friday-stopping-vms/
http://arnulfowing.blogspot.com.au/2012/10/how-to-startstop-hyper-v-machines-with.html
http://www.virtu-al.net/2010/01/06/powercli-shutdown-your-virtual-infrastructure/
https://www.vmware.com/support/developer/PowerCLI/PowerCLI41/html/Shutdown-VMGuest.html
https://helgeklein.com/blog/2013/09/script-gracefully-shut-down-all-vms-on-a-given-set-of-hosts-vmwarexendesktop/
http://pipe2text.com/?page_id=1889
http://www.informit.com/articles/article.aspx?p=1947698&seqNum=5
http://aikitsupport.com/how-to-change-the-computer-name-on-server-core/
http://blog.the-it-blog.co.uk/2013/08/01/how-to-remove-a-pc-from-a-domain-and-join-it-using-powershell/
http://www.codeproject.com/Articles/223002/Reboot-and-Resume-PowerShell-Script
http://www.florisvanderploeg.com/configuring-windows-server-2012-core-powershell/
http://www.florisvanderploeg.com/configuring-windows-server-2012-core-powershell/
http://www.florisvanderploeg.com/configuring-windows-server-2012-core-powershell/
http://www.pearsonitcertification.com/articles/article.aspx?p=2248808&seqNum=2
http://www.infoworld.com/article/2606206/data-center/116122-PowerShell-4.0-10-best-new-PowerShell-commands.html#slide10
http://www.windowsecurity.com/articles-tutorials/Windows_Server_2012_Security/use-windows-command-line-tools-and-powershell-cmdlets-manage-security-windows-server-2012-part1.html
https://www.hodgkins.net.au/powershell/automating-with-jenkins-and-powershell-on-windows-part-1/
http://www.ipbalance.com/programming/ms-powershell/1098-powershell-how-to-use-sshnet-library-for-cisco-on-windows-7.html
http://www.thomasmaurer.ch/2010/09/create-cisco-vlan-config-with-powershell/
https://zeleskitech.com/2014/08/02/sending-automated-commands-to-a-cisco-device-using-ssh-powershell/
http://www.serveradventures.com/the-adventures/get-ciscoconfig-using-powershell-to-backup-cisco-configurations
https://fskelly.wordpress.com/2013/10/09/backup-network-config-with-powershell/
http://www.powershellmagazine.com/2014/07/03/posh-ssh-open-source-ssh-powershell-module/
http://poshcode.org/2550 <== Cisco-Inventory.ps1 by Kenneth C 
https://github.com/chrisdee/Scripts/blob/master/PowerShell/Working/telnet/PowerShellTelnetRemoteSession.ps1



http://eniackb.blogspot.com.au/2009/07/how-to-disable-ipv6-in-windows-2008.html
http://booandjoel.me.uk/2014/07/18/building-a-hyper-v-2012-cluster/
!VM
https://www.simple-talk.com/sysadmin/virtualization/hyper-v-migration-technologies/
https://www.petri.com/use-hyper-v-replica-over-https-ssl-configure-certificates
http://blog.powerbiz.net.au/hyperv/how-to-create-self-signed-certificates-for-hyper-v-replication/
http://www.vkernel.ro/blog/configuring-hyper-v-replica-using-certificate-based-authentication-https
http://www.mokonamodoki.com/setting-up-hyper-v-replica-on-windows-2012-in-workgroup-mode-using-ssl-certificates
http://www.virtualizationadmin.com/kbase/VirtualizationTips/ServerVirtualization/MicrosoftHyper-VR2Tips/General/start-hyper-v-virtual-machine-failover-command-line.html
!IPAM
http://dalaris.com/ip-address-management-in-windows-server-2012-r2/
http://video.ch9.ms/sessions/teched/eu/2014/Labs/DBI-H306.pdf  <-- Building an ASP.NET MVC Application Using Azure
http://video.ch9.ms/sessions/teched/eu/2014/Labs/CDP-H313.pdf <-- Windows Server 2012 R2 – IP Address Management (IPAM) 
http://video.ch9.ms/sessions/teched/eu/2014/Labs/OFC-H211.pdf <-- Extending the Search Experience in SharePoint 2013 
http://video.ch9.ms/sessions/teched/eu/2014/Labs/EM-H324.pdf  <-- Troubleshooting AD Replication Errors

https://channel9.msdn.com/Events/MMS/2013/WS-B337  <== Save Time and Money: Automate Hyper-V with PowerShell and C#
https://channel9.msdn.com/Events/MMS/2013/IM-B291    <== Cisco Virtual Networking Solutions for Microsoft Hyper-V Environments
https://channel9.msdn.com/Events/MMS/2013/DV-B291 <== Microsoft Server 2012 Desktop Virtualization (VDI) on Dell Active Infrastructure
https://channel9.msdn.com/Events/MMS/2013/DC-B401 <== Advanced Automation Using Windows Powershell
https://channel9.msdn.com/Events/MMS/2013/SD-B302  <== Automating System Center Deployment with the Powershell Deployment Toolkit
https://channel9.msdn.com/Events/MMS/2013/UD-B314  <== Replacing BIOS With a UEFI Deployment
https://channel9.msdn.com/Events/MMS/2013

http://video.ch9.ms sessions teched eu 2014 Labs pdf <-- search criteria


https://www.geekbooks.me/book/view/ipv6-address-planning <== downloads are free , require reigstration
!Build a lab
https://technet.microsoft.com/en-au/library/dn268503.aspx  <== Walkthrough: Demonstrate IPAM in Windows Server 2012 R2

https://technet.microsoft.com/en-us/library/hh831491.aspx#BKMK_powershell

http://www.adminarsenal.com/admin-arsenal-blog/2015/10/
!Powershell scripts
!!Dynamic IP Address Change Email Notification
https://gallery.technet.microsoft.com/scriptcenter/Dynamic-IP-Address-Change-daf9a835
{{{
$scriptpath = $MyInvocation.MyCommand.Definition  
[string]$dir = Split-Path $scriptpath   
set-location $dir 
 
$oldip = gc .\ip.txt 
Write-Host "Your previous IP was: $oldip" 
$currentip = (New-Object net.webclient).downloadstring("http://api.ipify.org") 
while ($currentip -eq '') {$currentip = (New-Object net.webclient).downloadstring("http://api.ipify.org")} 
Write-Host "Your current IP is: $currentip" 
 
$smtpServer = "smtp.mail.com" 
$sender = "sender@mail.com" 
$users = "user1@gmail.com", "user2@hotmail.com"; 
$subject = "Your IP $currentip"  
$body = "Previous IP was $oldip"  
 
if ($oldip -ne $currentip) { 
    foreach ($user in $users) { 
    Write-Host "Sending email notification to $user" -ForegroundColor Green 
    $smtp = New-Object Net.Mail.SmtpClient($smtpServer, 587)  
    $smtp.EnableSsl = $true  
    $smtp.Credentials = New-Object System.Net.NetworkCredential("sender@email.com", "password");  
    $smtp.Send($sender, $user, $subject, $body) 
    } 
} 
 
$currentip | Out-File .\ip.txt -Force 
Write-Host "New IP saved in file is: $currentip"
}}}

!sending mail
{{{
##############################################################################
$From = "YourEmail@gmail.com"
$To = "AnotherEmail@YourDomain.com"
$Cc = "YourBoss@YourDomain.com"
$Attachment = "C:\temp\Some random file.txt"
$Subject = "Email Subject"
$Body = "Insert body text here"
$SMTPServer = "smtp.gmail.com"
$SMTPPort = "587"

Send-MailMessage -From $From -to $To -Cc $Cc -Subject $Subject `
-Body $Body -SmtpServer $SMTPServer -port $SMTPPort -UseSsl `
-Credential (Get-Credential) -Attachments $Attachment

##############################################################################
http://www.adminarsenal.com/admin-arsenal-blog/powershell-sending-email-with-gmail-example/
}}}
https://dougvitale.wordpress.com/2013/02/07/network-administration-commands-for-microsoft-windows-and-active-directory/
http://etutorials.org/Server+Administration/dns+windows+server/Chapter+13.+Managing+DNS+from+the+Command+Line/13.3+Managing+the+DNS+Server+Configuration/
http://www.powershellmagazine.com/2015/05/11/manage-your-public-dns-zones-with-azure-dns/
https://rcmtech.wordpress.com/2014/02/26/get-and-delete-dns-a-and-ptr-records-via-powershell/
http://www.labofapenetrationtester.com/2015/05/week-of-powershell-shells-day-5.html
http://www.lazywinadmin.com/2012/10/create-dns-entries-using-powershell-and.html

http://www.hitmaroc.co/questions-full/67171/turn-on-off-monitor
https://msdn.microsoft.com/en-us/library/windows/desktop/ms646260(v=vs.85).aspx
[[Set-DisplayOff.ps1]]
[[WakeUp]]
[[DisplayOff.bat]]
[[WakeUp.bat]]
!schedule scripts
[[sch]]
[[sch1]]


[[sendkey.ps1]]
http://www.newron.cz/doc/html/_mouse_control_8cs_source.html
https://code.msdn.microsoft.com/How-to-programmatically-d5df5d37
https://msdn.microsoft.com/en-us/library/windows/desktop/ms646260(v=vs.85).aspx




https://github.com/SNiels/WiiController/blob/master/WiiController/WinAPI.cs

http://stackoverflow.com/questions/713498/turn-on-off-monitor
http://stackoverflow.com/questions/12572441/sendmessage-sc-monitorpower-wont-turn-monitor-on-when-running-windows-8/14171736#14171736
https://robertsmit.wordpress.com/2014/08/20/create-a-new-network-load-balancing-nlb-cluster-on-windows-server-2012-r2-winserv-nlb/#comments
[[Create a New Network Load Balancing NLB Cluster On Windows Server 2012 R2|https://robertsmit.wordpress.com/2014/08/20/create-a-new-network-load-balancing-nlb-cluster-on-windows-server-2012-r2-winserv-nlb/]]

[[Hyper-v Virtual Machine Connection in Windows Server 2012R2 #hyper-v #winserv  |https://robertsmit.wordpress.com/2014/10/04/hyper-v-virtual-machine-connection-in-windows-server-2012r2-hyper-v-winserv/]]
!Create a New Network Load Balancing NLB Cluster On Windows Server 2012 R2 by Powershell script
{{{
#Set IP for NLB 
Write-Host "Set NLB IP and change Network adapter" -ForegroundColor yellow 
Rename-NetAdapter -Name "Ethernet 2" -NewName "NLB" 
New-NetIPAddress -IPAddress 10.255.255.93 -InterfaceAlias "NLB" -AddressFamily IPv4 -PrefixLength 24

#Set ExecutionPolicy 
Write-Host "Set ExecutionPolicy" -ForegroundColor yellow 
Set-ExecutionPolicy -scope LocalMachine RemoteSigned –force

#Add-WindowsFeature 
Write-Host "Add-WindowsFeature NLB" -ForegroundColor yellow 
add-WindowsFeature NLB 
add-WindowsFeature RSAT-NLB

#Variables for creating the new cluster 
Write-Host "Variables for creating the new cluster" -ForegroundColor yellow 
$ClusterFqdn = Read-Host "Enter NLB cluster Name FQDN" 
$InterfaceName = Read-Host "Enter interface name for NLB-adapter" 
$ClusterPrimaryIP = Read-Host "Enter cluster primary IP" 
$ClusterPrimaryIPSubnetMask = Read-Host "Enter subnetmask for cluster primary IP"

Write-Host "Choose cluster operation mode" 
Write-Host "1 – Unicast" 
Write-Host "2 – Multicast" 
Write-Host "3 – IGMP Multicast" 
switch (Read-Host "Enter the number for your chosen operation mode") 
{ 
1 {$OperationMode = "unicast"} 
2 {$OperationMode = "multicastcast"} 
3 {$OperationMode = "igmpmulticast"} 
default {Write-Warning "Invalid option, choose ‘1’, ‘2’ or ‘3’";return} 
}

#Creating new cluster 
Write-Host "Creating NLB Cluster…" -ForegroundColor yellow 
New-NlbCluster -ClusterName $ClusterFqdn -InterfaceName $InterfaceName -ClusterPrimaryIP $ClusterPrimaryIP -SubnetMask $ClusterPrimaryIPSubnetMask -OperationMode $OperationMode

#Removing default port rule for the new cluster 
Write-Host "Removing default port rule…" -ForegroundColor yellow 
Get-NlbClusterPortRule -HostName . | Remove-NlbClusterPortRule -Force

#Adding port rules

Add-NlbClusterPortRule -Protocol Tcp -Mode Multiple -Affinity Single -StartPort 80 -EndPort 80 -InterfaceName $InterfaceName | Out-Null 
Write-Host "Added port rule for http (tcp 80)" -ForegroundColor yellow

Add-NlbClusterPortRule -Protocol Tcp -Mode Multiple -Affinity Single -StartPort 443 -EndPort 443 -InterfaceName $InterfaceName | Out-Null 
Write-Host "Added port rule for https (tcp 443)" -ForegroundColor yellow

#Adding additional cluster nodes based on user input 
Write-Host "Give Second NLB host" -ForegroundColor yellow 
$Node2Fqdn = Read-Host "Enter 2e NLB node"

#Set Network Adapter 
Enter-PSSession -ComputerName $Node2Fqdn 
invoke-command -computername $Node2Fqdn -scriptblock { Rename-NetAdapter -Name "Ethernet 2" -NewName "NLB"} 
invoke-command -computername $Node2Fqdn -scriptblock { New-NetIPAddress -IPAddress 10.255.255.92 -InterfaceAlias "NLB" -AddressFamily IPv4 -PrefixLength 24} 
Write-Host "Placed NLB IP and changed NIC to NLB" -ForegroundColor yellow 
exit-PSSession

#Add-WindowsFeature 
Write-Host "Add-WindowsFeature NLB" -ForegroundColor yellow 
Enter-PSSession -ComputerName $Node2Fqdn 
invoke-command -computername $Node2Fqdn { add-WindowsFeature NLB} 
invoke-command -computername $Node2Fqdn { add-WindowsFeature RSAT-NLB} 
exit-pssession

#Add Remote Node To NLB 
Write-Host "Adding cluster node $Node2Fqdn" -ForegroundColor yellow 
Get-NlbCluster | Add-NlbClusterNode -NewNodeName $Node2Fqdn -NewNodeInterface NLB
}}}
https://robertsmit.wordpress.com/2014/08/20/create-a-new-network-load-balancing-nlb-cluster-on-windows-server-2012-r2-winserv-nlb/
schtasks /query /TN DisplayOff
schtasks /query /TN Wakeup
pause
schtasks /delete /TN DisplayOff
schtasks /delete /TN Wakeup

pause
schtasks /Create /TN DisplayOff  /TR \ps\displayoff /sc once /st 09:08
schtasks /Create /TN WakeUp  /TR \ps\WakeUp /sc once /st 09:10
schtasks /query /TN DisplayOff
schtasks /query /TN Wakeup

{{{
schtasks /query /TN Wakeup
schtasks /delete /TN Wakeup

pause
schtasks /Create /TN WakeUp  /sc minute /mo 5 /TR \ps\WakeUp
schtasks /query /TN Wakeup
}}}

!Wakeup.at
{{{
powershell /ps/Wakeup_key.ps1
}}}
!Wakeup_key.ps1
{{{
add-type -AssemblyName System.Windows.Forms
[System.Windows.Forms.SendKeys]::SendWait("o")
}}}
}}}
{{{
C:\Users\Sara>schtasks /Create /TN DisplayOff  /TR \ps\displayoff /sc once /st 22:50
SUCCESS: The scheduled task "DisplayOff" has successfully been created.

C:\Users\Sara>schtasks /Create /TN DisplayOff  /TR \ps\displayoff /sc once /st 22:52
WARNING: The task name "DisplayOff" already exists. Do you want to replace it (Y/N)? Y
SUCCESS: The scheduled task "DisplayOff" has successfully been created.

C:\Users\Sara>schtasks /Create /TN DisplayOff  /TR \ps\displayoff /sc once /st 22:56
WARNING: The task name "DisplayOff" already exists. Do you want to replace it (Y/N)? y
SUCCESS: The scheduled task "DisplayOff" has successfully been created.

C:\Users\Sara>schtasks /Create /TN WakeUp  /TR \ps\WakeUp /sc once /st 22:59
WARNING: The task name "WakeUp" already exists. Do you want to replace it (Y/N)? Y
ERROR: Access is denied.

C:\Users\Sara>schtasks /Create /TN WakeUp  /TR \ps\WakeUp /sc once /st 22:59
WARNING: The task name "WakeUp" already exists. Do you want to replace it (Y/N)? Y
ERROR: Access is denied.

C:\Users\Sara>schtasks /Create /TN WakeUp1  /TR \ps\WakeUp /sc once /st 22:59
SUCCESS: The scheduled task "WakeUp1" has successfully been created.

C:\Users\Sara>
}}}

http://www.howtogeek.com/51236/how-to-create-modify-and-delete-scheduled-tasks-from-the-command-line/
http://blog.omotech.com/?p=322
[[Who has Access To This Directory?|http://blogs.technet.com/b/canitpro/archive/2015/11/03/powershell-tips-who-has-access-to-this-directory.aspx]]
{{{
add-type -AssemblyName System.Windows.Forms
[System.Windows.Forms.SendKeys]::SendWait("o")
}}}
http://stackoverflow.com/questions/20529169/use-powershell-to-find-scheduled-tasks-set-to-wake-the-computer
http://www.madwithpowershell.com/2013/08/sleep-until-certain-time-with-powershell.html
http://ilantz.com/2012/12/21/windows-8-wakes-up-from-sleep-or-hibernation-unexpectedly/

http://superuser.com/questions/39584/what-is-the-command-to-use-to-put-your-computer-to-sleep-not-hibernate
http://superuser.com/questions/368829/how-do-i-create-a-wake-up-script-using-powershell

http://www.vexasoft.com/blogs/powershell/7255228-power-saving-with-powershell-a-script-to-hibernate-pcs-overnight-and-wake-them-in-the-morning

http://stackoverflow.com/questions/33790965/set-a-one-line-powershell-for-sleep-and-hibernate-to-turn-off

http://stackoverflow.com/questions/713498/turn-on-off-monitor
https://misterhenson.wordpress.com/2013/07/25/powershell-create-a-shortcut-to-power-off-monitors-windows-7/
http://www.digitallycreated.net/Blog/32/sleep-display

http://www.codeproject.com/Articles/12794/Complete-Guide-on-How-To-Turn-A-Monitor-On-Off-Sta <== C#
https://www.autoitscript.com/forum/topic/151104-monitor-off-screensaver/
https://www.snip2code.com/Snippet/687114/Powershell-script-to-turn-display-off/ <== C# with powershell
https://www.daniweb.com/programming/software-development/code/367279/turn-off-your-monitor <== C#
http://stackoverflow.com/questions/12572441/sendmessage-sc-monitorpower-wont-turn-monitor-on-when-running-windows-8 <== ???

http://code.activestate.com/lists/python-list/601329/ <== python

http://www.sevenforums.com/3146239-post13.html <== powershell /C#
https://autohotkey.com/board/topic/60699-turn-off-monitor-run-type-commands-turn-on-mon/ ???
https://autohotkey.com/board/topic/25339-how-to-turn-off-monitor/page-2
http://scsharp.tiddlyspot.com/
http://sdiabetes.tiddlyspot.com/
http://sccna.tiddlyspot.com
Python For Offensive PenTest: A Complete Practical Course
Forex Trading Secrets of the Pros With Amazon's AWS
Photography Masterclass: Your Complete Guide to Photography
SAP HANA Internet of Things(IoT):Raspberry, Uno, PubNub, UI5
Introduction to Internet of Things(IoT) using Arduino
Introduction to Arduino
{{{

[HQEDC]: PS C:\Users\Administrator\Documents> $PSVersionTable

Name                           Value
----                           -----
PSVersion                      4.0
WSManStackVersion              3.0
SerializationVersion           1.1.0.1
CLRVersion                     4.0.30319.34014
BuildVersion                   6.3.9600.16394
PSCompatibleVersions           {1.0, 2.0, 3.0, 4.0}
PSRemotingProtocolVersion      2.2
}}}
{{{
[HQEDC]: PS C:\Users\Administrator\Documents> $PSVersionTable.PSVersion

Major  Minor  Build  Revision
-----  -----  -----  --------
4      0      -1     -1
}}}
{{{
[HQEDC]: PS C:\Users\Administrator\Documents>  $psversiontable.psversion.major
4
}}}
{{{
[HQEDC]: PS C:\Users\Administrator\Documents> Get-WmiObject -Class Win32_OperatingSystem | Format-Table Caption, Service
PackMajorVersion -AutoSize

Caption                                                ServicePackMajorVersion
-------                                                -----------------------
Microsoft Windows Server 2012 R2 Datacenter Evaluation                       0
}}}
{{{
[HQEDC]: PS C:\Users\Administrator\Documents> (Get-ItemProperty -Path 'HKLM:\Software\Microsoft\NET Framework Setup\NDP\
v4\Full' -ErrorAction SilentlyContinue).Version -like '4.5*'
True
}}}
Ref: http://mikefrobbins.com/2015/01/08/how-to-check-the-powershell-version-and-install-a-new-version/