├── LICENSE
├── NodePS
├── Default
│ ├── config
│ │ ├── CustomJob.ps1
│ │ ├── ServerConfig.ps1
│ │ └── ThreadConfig.ps1
│ └── http
│ │ ├── css
│ │ ├── 960.css
│ │ ├── ie.css
│ │ ├── ie6.css
│ │ ├── print.css
│ │ └── screen.css
│ │ ├── example1.ps1
│ │ ├── example2.ps1
│ │ ├── example3.ps1
│ │ ├── example4.ps1
│ │ ├── example5.ps1
│ │ ├── example6.ps1
│ │ ├── favicon.ico
│ │ ├── images
│ │ ├── add-on-skype.png
│ │ ├── avatar.jpg
│ │ ├── bg
│ │ │ ├── arrow1.png
│ │ │ ├── arrow2.png
│ │ │ ├── bottom.png
│ │ │ ├── bottom2.png
│ │ │ ├── download.png
│ │ │ ├── email.png
│ │ │ ├── error.gif
│ │ │ ├── message.png
│ │ │ ├── name.png
│ │ │ ├── quote.jpg
│ │ │ ├── sfere.jpg
│ │ │ ├── spinner.gif
│ │ │ ├── success.gif
│ │ │ └── top-bg.png
│ │ ├── clear.gif
│ │ ├── fancyzoom
│ │ │ ├── bl.gif
│ │ │ ├── bl.png
│ │ │ ├── bm.gif
│ │ │ ├── bm.png
│ │ │ ├── br.gif
│ │ │ ├── br.png
│ │ │ ├── closebox.gif
│ │ │ ├── closebox.png
│ │ │ ├── loading.gif
│ │ │ ├── ml.gif
│ │ │ ├── ml.png
│ │ │ ├── mr.gif
│ │ │ ├── mr.png
│ │ │ ├── tl.gif
│ │ │ ├── tl.png
│ │ │ ├── tm.gif
│ │ │ ├── tm.png
│ │ │ ├── tr.gif
│ │ │ └── tr.png
│ │ ├── follow-me.gif
│ │ ├── logo.png
│ │ ├── logo.small.gif
│ │ ├── portfolio
│ │ │ ├── 001.big.jpg
│ │ │ ├── 002.big.jpg
│ │ │ ├── 003.big.jpg
│ │ │ ├── 004.big.jpg
│ │ │ ├── 005.big.jpg
│ │ │ └── 006.big.jpg
│ │ └── send-mail.gif
│ │ ├── index.htm
│ │ ├── index.ps1
│ │ └── js
│ │ ├── cufon-yui.js
│ │ ├── cufon-yui.old.js
│ │ ├── dustismo_400.font.js
│ │ ├── fancyzoom.js
│ │ ├── form-contact-validate.js
│ │ ├── jquery.js
│ │ ├── mootools-yui-compressed.js
│ │ ├── scroll.js
│ │ └── unitpngfix.js
├── NodePS.psd1
├── NodePS.psm1
├── Private
│ ├── Get-404PageContent.ps1
│ ├── Get-Authentication.ps1
│ ├── Get-DirectoryContent.ps1
│ ├── Get-MimeType.ps1
│ ├── Get-NodePSPostStream.ps1
│ ├── Get-NodePSQueryString.ps1
│ ├── Get-NodePSThreadScriptBlock.ps1
│ ├── Get-NodePSWelcomeBanner.ps1
│ ├── Invoke-AsyncHTTPRequest.ps1
│ ├── Invoke-BackgroundJob.ps1
│ ├── New-NodePSLogHash.ps1
│ ├── New-NodePSTimeStamp.ps1
│ ├── Register-NodePSCertificate.ps1
│ ├── Request-NodePSCertificate.ps1
│ ├── Start-NodePSLogParser.ps1
│ ├── Test-ContentFiltering.ps1
│ ├── Test-IPRestriction.ps1
│ ├── Test-IPSettings.ps1
│ └── Write-NodePSLog.ps1
└── Public
│ └── Start-NodePSServer.ps1
└── README.md
/NodePS/Default/config/CustomJob.ps1:
--------------------------------------------------------------------------------
1 | # Do nothing
--------------------------------------------------------------------------------
/NodePS/Default/config/ServerConfig.ps1:
--------------------------------------------------------------------------------
1 | # NodePS Server Configuration
2 |
3 | # Number of concurrent listening thread
4 | # Default is equal to the number of processor
5 | $NodePSConfig.Threads = (Get-WmiObject Win32_ComputerSystem).NumberOfProcessors
6 |
7 |
8 | # Cache mode can be used for better speed in production
9 | $NodePSConfig.CachedMode = $false
--------------------------------------------------------------------------------
/NodePS/Default/config/ThreadConfig.ps1:
--------------------------------------------------------------------------------
1 | # NodePS Server Threads Configuration
2 |
3 | # Default Document
4 | $DefaultDocument = "index.ps1"
5 |
6 | # Basic Authentication
7 | # Options: On, Off
8 | $BasicAuthentication = "Off"
9 |
10 | # Windows Authentication
11 | # Options: On, Off
12 | $WindowsAuthentication = "On"
13 |
14 | # DirectoryBrowsing
15 | # Options: On, Off
16 | $DirectoryBrowsing = "Off"
17 |
18 | # IP Restriction
19 | # Options: On, Off
20 | $IPRestriction = "Off"
21 | $IPWhiteList = "::1 127.0.0.1"
22 |
23 | # Content Filtering
24 | # Options: On, Off
25 | $ContentFiltering = "Off"
26 | $ContentFilterBlackList = "audio/mpeg video/mpeg"
--------------------------------------------------------------------------------
/NodePS/Default/http/css/960.css:
--------------------------------------------------------------------------------
1 | .container_12,.container_16{margin-left:auto;margin-right:auto;width:960px;}.grid_1,.grid_2,.grid_3,.grid_4,.grid_5,.grid_6,.grid_7,.grid_8,.grid_9,.grid_10,.grid_11,.grid_12,.grid_13,.grid_14,.grid_15,.grid_16{display:inline;float:left;margin-left:10px;margin-right:10px}.container_12 .grid_3,.container_16 .grid_4{width:220px}.container_12 .grid_6,.container_16 .grid_8{width:460px}.container_12 .grid_9,.container_16 .grid_12{width:700px}.container_12 .grid_12,.container_16 .grid_16{width:940px;}.alpha{margin-left:0}.omega{margin-right:0}.container_12 .grid_1{width:60px}.container_12 .grid_2{width:140px}.container_12 .grid_4{width:300px}.container_12 .grid_5{width:380px}.container_12 .grid_7{width:540px}.container_12 .grid_8{width:620px}.container_12 .grid_10{width:780px}.container_12 .grid_11{width:860px}.container_16 .grid_1{width:40px}.container_16 .grid_2{width:100px}.container_16 .grid_3{width:160px}.container_16 .grid_5{width:280px}.container_16 .grid_6{width:340px}.container_16 .grid_7{width:400px}.container_16 .grid_9{width:520px}.container_16 .grid_10{width:580px}.container_16 .grid_11{width:640px}.container_16 .grid_13{width:760px}.container_16 .grid_14{width:820px}.container_16 .grid_15{width:880px}.container_12 .prefix_3,.container_16 .prefix_4{padding-left:240px}.container_12 .prefix_6,.container_16 .prefix_8{padding-left:480px}.container_12 .prefix_9,.container_16 .prefix_12{padding-left:720px}.container_12 .prefix_1{padding-left:80px}.container_12 .prefix_2{padding-left:160px}.container_12 .prefix_4{padding-left:320px}.container_12 .prefix_5{padding-left:400px}.container_12 .prefix_7{padding-left:560px}.container_12 .prefix_8{padding-left:640px}.container_12 .prefix_10{padding-left:800px}.container_12 .prefix_11{padding-left:880px}.container_16 .prefix_1{padding-left:60px}.container_16 .prefix_2{padding-left:120px}.container_16 .prefix_3{padding-left:180px}.container_16 .prefix_5{padding-left:300px}.container_16 .prefix_6{padding-left:360px}.container_16 .prefix_7{padding-left:420px}.container_16 .prefix_9{padding-left:540px}.container_16 .prefix_10{padding-left:600px}.container_16 .prefix_11{padding-left:660px}.container_16 .prefix_13{padding-left:780px}.container_16 .prefix_14{padding-left:840px}.container_16 .prefix_15{padding-left:900px}.container_12 .suffix_3,.container_16 .suffix_4{padding-right:240px}.container_12 .suffix_6,.container_16 .suffix_8{padding-right:480px}.container_12 .suffix_9,.container_16 .suffix_12{padding-right:720px}.container_12 .suffix_1{padding-right:80px}.container_12 .suffix_2{padding-right:160px}.container_12 .suffix_4{padding-right:320px}.container_12 .suffix_5{padding-right:400px}.container_12 .suffix_7{padding-right:560px}.container_12 .suffix_8{padding-right:640px}.container_12 .suffix_10{padding-right:800px}.container_12 .suffix_11{padding-right:880px}.container_16 .suffix_1{padding-right:60px}.container_16 .suffix_2{padding-right:120px}.container_16 .suffix_3{padding-right:180px}.container_16 .suffix_5{padding-right:300px}.container_16 .suffix_6{padding-right:360px}.container_16 .suffix_7{padding-right:420px}.container_16 .suffix_9{padding-right:540px}.container_16 .suffix_10{padding-right:600px}.container_16 .suffix_11{padding-right:660px}.container_16 .suffix_13{padding-right:780px}.container_16 .suffix_14{padding-right:840px}.container_16 .suffix_15{padding-right:900px}.clear{clear:both;display:block;overflow:hidden;visibility:hidden;width:0;height:0}.clearfix:after{clear:both;content:' ';display:block;font-size:0;line-height:0;visibility:hidden;width:0;height:0}.clearfix{display:inline-block}* html .clearfix{height:1%}.clearfix{display:block}
--------------------------------------------------------------------------------
/NodePS/Default/http/css/ie.css:
--------------------------------------------------------------------------------
1 | /* -----------------------------------------------------------------------
2 |
3 |
4 | Blueprint CSS Framework 0.7.1
5 | http://blueprintcss.googlecode.com
6 |
7 | * Copyright (c) 2007-2008. See LICENSE for more info.
8 | * See README for instructions on how to use Blueprint.
9 | * For credits and origins, see AUTHORS.
10 | * This is a compressed file. See the sources in the 'src' directory.
11 |
12 | ----------------------------------------------------------------------- */
13 |
14 | /* ie.css */
15 | /*body {text-align:center;}*/
16 | .container {text-align:left;}
17 | * html .column {overflow-x:hidden;}
18 | * html legend {margin:-18px -8px 16px 0;padding:0;}
19 | ol {margin-left:2em;}
20 | sup {vertical-align:text-top;}
21 | sub {vertical-align:text-bottom;}
22 | html>body p code {*white-space:normal;}
23 | hr {margin:-8px auto 11px;}
24 | .clearfix, .container {display:inline-block;}
25 | * html .clearfix, * html .container {height:1%;}
--------------------------------------------------------------------------------
/NodePS/Default/http/css/ie6.css:
--------------------------------------------------------------------------------
1 | .fixed-column {
2 | position:absolute; /* position fixed for IE6 */
3 | /*Expression*/
4 | top:expression(55+((e=document.documentElement.scrollTop)?e:document.body.scrollTop)+'px');
5 | left:expression(55+((e=document.documentElement.scrollLeft)?e:document.body.scrollLeft)+'px');width:220px;height:720px;
6 | }
7 | .top-bg {width:100%;height:110px;background:url('../images/top-bg.png') top center;z-index:99;position:absolute;
8 | top:expression(0+((e=document.documentElement.scrollTop)?e:document.body.scrollTop)+'px');
9 | left:expression(0+((e=document.documentElement.scrollLeft)?e:document.body.scrollLeft)+'px');}
10 |
11 | .home h1 {line-height:70px;}
12 | ul#nav {font-family:dustismo,"century gothic";}
13 | .bottom-bg {background:none;}
14 | .download {width:215px;height:206px;position:absolute;top:0px;left:0px;z-index:110;}
15 |
--------------------------------------------------------------------------------
/NodePS/Default/http/css/print.css:
--------------------------------------------------------------------------------
1 | /* -----------------------------------------------------------------------
2 |
3 |
4 | Blueprint CSS Framework 0.7.1
5 | http://blueprintcss.googlecode.com
6 |
7 | * Copyright (c) 2007-2008. See LICENSE for more info.
8 | * See README for instructions on how to use Blueprint.
9 | * For credits and origins, see AUTHORS.
10 | * This is a compressed file. See the sources in the 'src' directory.
11 |
12 | ----------------------------------------------------------------------- */
13 |
14 | /* print.css */
15 | body {line-height:1.5;font-family:"Helvetica Neue", Arial, Helvetica, sans-serif;color:#000;background:none;font-size:10pt;}
16 | .container {background:none;}
17 | hr {background:#ccc;color:#ccc;width:100%;height:2px;margin:2em 0;padding:0;border:none;}
18 | hr.space {background:#fff;color:#fff;}
19 | h1, h2, h3, h4, h5, h6 {font-family:"Helvetica Neue", Arial, "Lucida Grande", sans-serif;}
20 | code {font:.9em "Courier New", Monaco, Courier, monospace;}
21 | img {float:left;margin:1.5em 1.5em 1.5em 0;}
22 | a img {border:none;}
23 | p img.top {margin-top:0;}
24 | blockquote {margin:1.5em;padding:1em;font-style:italic;font-size:.9em;}
25 | .small {font-size:.9em;}
26 | .large {font-size:1.1em;}
27 | .quiet {color:#999;}
28 | .hide {display:none;}
29 | a:link, a:visited {background:transparent;font-weight:700;text-decoration:underline;}
30 | a:link:after, a:visited:after {content:" (" attr(href) ") ";font-size:90%;}
--------------------------------------------------------------------------------
/NodePS/Default/http/css/screen.css:
--------------------------------------------------------------------------------
1 | /* -----------------------------------------------------------------------
2 | Template Name: Your Inspiration Folio (free version)
3 | Template URI: http://www.yourinspirationweb.com/en/free-website-template-present-your-portfolio-online-in-a-single-webpage/
4 | Version: 1.0
5 | Author: Your Inspiraton Web
6 | Author URI: http://www.yourinspirationweb.com/
7 | Description:
8 | Based on Blueprint CSS Framework 0.7.1
9 | ----------------------------------------------------------------------- */
10 |
11 | /***********************************************************************
12 | ******************* reset.css ******************************************
13 | ************************************************************************/
14 |
15 | html, body, div, span, object, iframe, h1, h2, h3, h4, h5, h6, p, blockquote, pre, a, abbr, acronym, address, code, del, dfn, em, img, q, dl, dt, dd, ol, ul, li, fieldset, form, label, legend, table, caption, tbody, tfoot, thead, tr, th, td {margin:0;padding:0;border:0;font-weight:inherit;font-style:inherit;font-size:100%;font-family:inherit;vertical-align:baseline;}
16 | body { line-height:1.5; }
17 | table { border-collapse:separate; border-spacing:0; }
18 | caption, th, td { text-align:left; font-weight:normal; }
19 | table, td, th { vertical-align: middle; }
20 | blockquote:before, blockquote:after, q:before, q:after { content:""; }
21 | blockquote, q { quotes:"" ""; }
22 | a img { border:none; }
23 | .clearer { height: 0px; overflow: hidden; margin: 0px; clear: both; }
24 |
25 | /***********************************************************************
26 | ******************* typography *****************************************
27 | ************************************************************************/
28 |
29 | /* Titoli */
30 | h1, h2, h3, h4, h5, h6 { font-weight: bold; color:#111;}
31 | h1 { font-size:120%; line-height:1; margin-bottom:0.5em; }
32 | h2 { font-size:105%; margin-bottom:0.75em; }
33 | h3 { font-size:100%; line-height:1; margin-bottom:1em; }
34 | h4 { font-size:1.2em; line-height:1.25; margin-bottom:1.25em; }
35 | h5 { font-size:1em; margin-bottom:1.5em; }
36 | h6 { font-size:1em; }
37 | h1 img, h2 img, h3 img, h4 img, h5 img, h6 img { margin:0;}
38 |
39 | /* Paragrafi */
40 | p { padding: 4px 0 4px 0; line-height: 20px; }
41 | p img.left { float:left;margin:1.5em 1.5em 1.5em 0;padding:0;}
42 | p img.right {float:right;margin:1.5em 0 1.5em 1.5em;}
43 |
44 | /* Link */
45 | a { color:#009; text-decoration:none;}
46 | a:link, a:visited { color: #009; text-decoration: none; }
47 | a:active, a:hover { color: #621303; text-decoration: underline }
48 |
49 |
50 | /* Formattazione */
51 | blockquote {margin:1.5em;color:#666;font-style:italic;}
52 | strong { font-weight:bold; }
53 | em, dfn { font-style:italic; }
54 | dfn { font-weight:bold; }
55 | sup, sub { line-height:0; }
56 | abbr, acronym { border-bottom:1px dotted #666; }
57 | address {margin:1.5em 0 0.5em 0;text-align:right;font-style:italic;}
58 | del { color:#666;}
59 | pre { margin:1.5em 0; white-space:pre;}
60 | pre, code, tt { font:1em 'andale mono', 'lucida console', monospace; line-height:1.5; }
61 | caption {background:#eee;}
62 | .small { font-size:.9em; margin-bottom:1.875em; line-height:1.875em;}
63 | .large { font-size:1.2em; line-height:2.5em; margin-bottom:1.25em;}
64 | .hide { display:none; }
65 | .quiet { color:#666; }
66 | .loud { color:#000; }
67 | .highlight { background:#ff0;}
68 | .added { background:#060; color:#fff; }
69 | .removed { background:#900; color:#fff; }
70 | .first { margin-left:0; padding-left:0; }
71 | .last { margin-right:0; padding-right:0; }
72 | .top { margin-top:0; padding-top:0; }
73 | .bottom { margin-bottom:0; padding-bottom:0; }
74 | .center { text-align: center; }
75 |
76 | /*liste e tabelle*/
77 | li { margin: 0 0 0 25px; line-height: 22px; }
78 | ul, ol {margin:0 1.5em 1.5em 1.5em; }
79 | ul { list-style-type: disc; }
80 | ol { list-style-type:decimal; }
81 | dl { margin:0 0 1.5em 0; }
82 | dl dt { font-weight:bold; }
83 | dd { margin-left:1.5em; }
84 | table { margin-bottom:1.4em; width:100%; }
85 | th { font-weight: bold; background:#C3D9FF; }
86 | th, td { padding: 4px 10px 4px 5px; }
87 | tr.even td {background:#E5ECF9;}
88 | tfoot {font-style:italic;}
89 |
90 | /* forms.css */
91 | label {vertical-align:middle;font-weight:bold;float:left;width:120px;display:block;clear:left;margin:0;text-align:left;font-size:1em;line-height:1.25;}
92 | fieldset {padding:1.4em 0 0 0;margin:0;}
93 | legend {font-weight:bold;font-size:1.2em;}
94 | input.text, input.title, select,textarea, textarea.text {margin:0.5em 0;color:#5c5c5c;border:none;background-color:#d2d0d1;font-weight:bold;font-style:italic;font-family:"georgia","Helvetica Neue",Arial,Helvetica,sans-serif;}
95 | input.text:focus,input.title:focus,select:focus,.errorForm:focus,textarea:focus {background-color:#dedddd;}
96 | input.text, input.title, input.errorForm, textarea.errorForm {width:270px;padding:10px 0 10px 50px;font-size:1.0em;}
97 | input.title {font-size:1.5em;}
98 | textarea {width:270px;height:120px;padding:10px 0 10px 50px;font-size:1.0em;}
99 | .buttonContactForm {width:80px;font-size:1.0em;margin:2em 0;color:#fbfaf5;background-color:#a6a18b;padding:10px;font-size:1.1em;border:none;}
100 | input.errorForm, textarea.errorForm {background:#fddada;margin:0.5em 0;color:#5c5c5c;font-family:"georgia";font-weight:bold;font-style:italic;border:none;}
101 | .buttonForm {padding:0;margin:0;}
102 | .button {width:120px;font-weight:bold;font-size:0.95em;margin:0.5em 0 0.5em 100px;color:#5c5c5c;background-color:#d2d0d1;padding:10px;border:none;font-family:"georgia";}
103 |
104 | .download {width:215px;height:206px;position:fixed;top:0px;left:0px;z-index:110;}
105 | /*******************************************************************************
106 | ************************* web site ****************************************
107 | *******************************************************************************/
108 | body {font-size:70%;color:#222;background:#eaeaea url('../images/bg/sfere.jpg') no-repeat top center fixed;font-family: verdana,Arial,sans-serif;}
109 | .top-bg {width:100%;height:110px;position:fixed;background:url('../images/bg/top-bg.png') top center;top:0px;left:0px;z-index:1;}
110 | .bottom-bg {width:100%;height:67px;position:fixed;background:url('../images/bg/bottom.png') bottom center;bottom:0px;left:0px;z-index:1;}
111 | .fixed-column {position:fixed;width:220px;height:720px!important;z-index:100;text-align:center;}
112 | img.logo {padding:10px 0 0 0;}
113 |
114 | .right-column {float:right!important;}
115 |
116 | /*************************************************
117 | /*navigation*/
118 | /*************************************************/
119 | ul#nav {list-style-type:none;margin:10px 0;padding:0;text-align:center;}
120 | ul#nav li {font-size:300%;line-height:30px;padding:7px 0;margin:0;}
121 | ul#nav li a:link,ul#nav li a:visited {color:#878484;text-decoration:none;}
122 | ul#nav li a:hover,ul#nav li a:active {color:#a61607;text-decoration:none;}
123 |
124 | /*************************************************
125 | /*start home*/
126 | /*************************************************/
127 | .home {margin:108px 0 0 0;background:#eaeaea;width:660px!important;border-top:20px solid #fefcfc;border-left:20px solid #fefcfc;border-right:20px solid #fefcfc;height:auto!important;height:310px;min-height:310px;}
128 | .home-bottom-bg {background:#eaeaea url('../images/bg/arrow1.png') top center no-repeat;width:700px;height:170px;padding:0 0 150px 0;}
129 | /*end home*/
130 |
131 | /*************************************************
132 | /*about*/
133 | /*************************************************/
134 | .about {margin:108px 0 0 0;background:#eaeaea;width:660px!important;border-top:20px solid #d2d1d1;border-left:20px solid #d2d1d1;border-right:20px solid #d2d1d1;height:auto!important;height:310px;min-height:310px;}
135 | .about-bottom-bg {background:#eaeaea url('../images/bg/arrow2.png') top center no-repeat;width:700px;height:170px;padding:0 0 150px 0;}
136 | .container-about {padding:15px 0 30px 30px;}
137 | .container-about p span {color:#901003;}
138 | .avatar-image,.contact-info {width:180px!important;}
139 | img.avatar {margin:84px 0 0 30px;}
140 | /*end about*/
141 |
142 | /*************************************************
143 | /*portfolio page*/
144 | /*************************************************/
145 | .portfolio {margin:108px 0 0 0;background:#eaeaea;width:660px!important;border-top:20px solid #fefcfc;border-left:20px solid #fefcfc;border-right:20px solid #fefcfc;height:auto!important;height:310px;min-height:310px;}
146 | .portfolio-bottom-bg {background:#eaeaea url('../images/bg/arrow1.png') top center no-repeat;width:700px;height:170px;padding:0 0 150px 0;}
147 | .container-portfolio {padding:15px 0 30px 30px;}
148 | .portfolio-quote {background:#eaeaea url('../images/bg/quote.jpg') 0px 30px no-repeat;padding:45px 0 30px 50px;}
149 | .photo a:link img,.photo a:visited img {margin:1em 0.5em;background:#fff;padding:0.5em;border:1px solid #eaeaea;float:left;}
150 | .photo a:hover img,.photo a:active img {border:1px solid #999;background:#fff;}
151 | /*end portfolio*/
152 |
153 | /*************************************************
154 | /*contact page*/
155 | /*************************************************/
156 | .contact {margin:108px 0 0 0;background:#eaeaea;width:660px!important;border-top:20px solid #d2d1d1;border-left:20px solid #d2d1d1;border-right:20px solid #d2d1d1;height:auto!important;height:310px;min-height:310px;}
157 | .contact-bottom-bg {background:#eaeaea url('../images/bg/arrow2.png') top center no-repeat;width:700px;height:170px;padding:0 0 150px 0;}
158 | .container-contact {padding:15px 0 30px 30px;}
159 | .name {background:url('../images/bg/name.png') no-repeat 10px 0px;}
160 | .mail {background:url('../images/bg/email.png') no-repeat 10px 0px;}
161 | .message {background:url('../images/bg/message.png') no-repeat 10px 0px;}
162 | .contact-info {width:230px!important;}
163 | p.title {margin:40px 0 0 0;font-size:120%;color:#a61607;font-weight:bold;}
164 | img.contact-logo {margin:30px 0 10px 105px;}
165 | .contact-info p span {color:#901003;}
166 | #log_res {height:auto;margin:0;}
167 | #log_wait.ajax-loading {background: url('../images/bg/spinner.gif') no-repeat center;height:16px;margin:0 25px 0 0;}
168 | .error {background:url('../images/bg/error.gif') no-repeat top center;padding:22px 0 0 80px;width:240px;height:43px;color:#a61607;font-weight:bold;}
169 | .success {background:url('../images/bg/success.gif') no-repeat top center;padding:22px 0 0 80px;width:240px;height:43px;color:green;font-weight:bold;}
170 | /*end contact page*/
171 |
172 | /*************************************************
173 | /*credits*/
174 | /*************************************************/
175 | .credits {text-align:right;padding:10px 10px 0 0;}
176 | .credits a:link,.credits a:visited {color:#901003;text-decoration:none;}
177 | .credits a:hover, credits a:active {color:#ea5707;text-decoration:none;}
178 |
179 | /*************************************************
180 | /*heading*/
181 | /*************************************************/
182 | .home h1, h2, h3, h4 {font-size:450%;font-family:dustismo,"century gothic";font-weight:normal;text-align:center;padding:0.5em;margin:0;word-spacing:-5px;letter-spacing:-3px;color:#878484;}
183 | .home h1 span {color:#a61607;}
184 | h2 {text-align:left;font-size:450%;padding:0;color:#a61607;}
185 | h3 {text-align:right;font-size:250%;padding:0;color:#a61607;}
186 | h4 {text-align:left;font-size:185%;padding:0;word-spacing:0px;letter-spacing:-1px;line-height:1;}
187 |
188 | .right {text-align:right;}
189 |
190 | /*fancyzoom*/
191 | img.loading {width:42px!important;height:42px!important;}
192 | p.foto_caption {margin:1em 1em 1em 0;font-size:120%;}
--------------------------------------------------------------------------------
/NodePS/Default/http/example1.ps1:
--------------------------------------------------------------------------------
1 | # In this example, you see how to use Powershell commands
2 | # $(PSCommand) should work with html codes
3 | @"
4 | $(Write-Host Hello World!)
5 |
6 |
7 |
8 | Sample Web Site Template - PoSH Server
9 |
10 |
11 |
13 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
39 |
40 |
41 |
42 |
43 |
44 |
45 |
46 |
47 |
48 |
49 |
50 |
51 |
57 |
58 |
59 |
60 |
61 |
62 |
63 |
64 |
65 |
66 |
67 |
68 |
69 |
70 |
71 |
72 |
73 |
74 |
75 |
76 |
77 |
78 |
127 |
128 |
129 |
130 |
131 |
132 |
133 |
134 |
135 | Welcome to PoSH Server! You can use Powershell commands with html codes. Let's get date: $(Get-Date)
136 |
137 |
138 |
139 |
140 |
141 |
142 |
143 |
144 |
145 |
146 |
147 |
148 |
149 |
150 |
About
151 |
152 |
153 | In the About page you can insert some information on yourself: title of study,
154 | eventual training courses attended, certificates, diplomas.
155 |
156 |
157 |
158 | Or you can describe your dreams, your work experiences... in a few words everything
159 | that can represent you on the web in a decisive and original way.
160 |
161 |
162 |
163 | Insert a small picture or even a cartoon just like the one I have inserted: nowdays illustrations are the trend!
164 |
165 |
166 |
167 |
168 |
169 |
170 |
171 |
172 |
173 |
174 |
175 |
176 |
177 |
178 |
179 |
180 |
181 |
182 |
183 |
184 |
185 |
Portfolio
186 |
187 |
188 |
189 |
190 |
191 |
192 |
I hope you like my work and my work speaks for me.
193 |
194 |
195 |
196 |
197 |
198 |
199 |
200 |
201 |
202 |
207 |
208 |
213 |
214 |
219 |
220 |
225 |
226 |
231 |
232 |
237 |
238 |
243 |
244 |
249 |
250 |
255 |
256 |
261 |
262 |
263 |
264 |
265 |
266 |
267 |
268 |
269 |
270 |
271 |
272 |
273 |
322 |
323 |
324 |
325 |
326 |
327 |
328 |
329 |
330 |
331 |
334 |
335 |
336 | "@
--------------------------------------------------------------------------------
/NodePS/Default/http/example2.ps1:
--------------------------------------------------------------------------------
1 | # Also you can put your commands before @""@
2 | $(Write-Host Hello World Example2!)
3 | @"
4 |
5 |
6 |
7 | Sample Web Site Template - PoSH Server
8 |
9 |
10 |
12 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
38 |
39 |
40 |
41 |
42 |
43 |
44 |
45 |
46 |
47 |
48 |
49 |
50 |
56 |
57 |
58 |
59 |
60 |
61 |
62 |
63 |
64 |
65 |
66 |
67 |
68 |
69 |
70 |
71 |
72 |
73 |
74 |
75 |
76 |
77 |
126 |
127 |
128 |
129 |
130 |
131 |
132 |
133 |
134 | Welcome to PoSH Server! You can use Powershell commands with html codes. Let's get date: $(Get-Date)
135 |
136 |
137 |
138 |
139 |
140 |
141 |
142 |
143 |
144 |
145 |
146 |
147 |
148 |
149 |
About
150 |
151 |
152 | In the About page you can insert some information on yourself: title of study,
153 | eventual training courses attended, certificates, diplomas.
154 |
155 |
156 |
157 | Or you can describe your dreams, your work experiences... in a few words everything
158 | that can represent you on the web in a decisive and original way.
159 |
160 |
161 |
162 | Insert a small picture or even a cartoon just like the one I have inserted: nowdays illustrations are the trend!
163 |
164 |
165 |
166 |
167 |
168 |
169 |
170 |
171 |
172 |
173 |
174 |
175 |
176 |
177 |
178 |
179 |
180 |
181 |
182 |
183 |
184 |
Portfolio
185 |
186 |
187 |
188 |
189 |
190 |
191 |
I hope you like my work and my work speaks for me.
192 |
193 |
194 |
195 |
196 |
197 |
198 |
199 |
200 |
201 |
206 |
207 |
212 |
213 |
218 |
219 |
224 |
225 |
230 |
231 |
236 |
237 |
242 |
243 |
248 |
249 |
254 |
255 |
260 |
261 |
262 |
263 |
264 |
265 |
266 |
267 |
268 |
269 |
270 |
271 |
272 |
321 |
322 |
323 |
324 |
325 |
326 |
327 |
328 |
329 |
330 |
333 |
334 |
335 | "@
--------------------------------------------------------------------------------
/NodePS/Default/http/example3.ps1:
--------------------------------------------------------------------------------
1 | # You can use ps1 files as templates
2 | # Let's import one of them
3 | @"
4 | $(Write-Host Hello World Example3!)
5 | $(. $HomeDirectory\index.ps1)
6 | "@
--------------------------------------------------------------------------------
/NodePS/Default/http/example4.ps1:
--------------------------------------------------------------------------------
1 | # You can also use html files as templates
2 | # Let's import one of them
3 | # But we only get content of html files, you can't execute Powershell in them.
4 | @"
5 | $(Write-Host Hello World Example4!)
6 | $(Get-Content "$HomeDirectory\index.htm")
7 | "@
--------------------------------------------------------------------------------
/NodePS/Default/http/example5.ps1:
--------------------------------------------------------------------------------
1 | # You can post values to Powershell
2 | # Example: http://localhost:8080/example5.ps1?command=Date
3 | # But we only get content of html files, you can't execute Powershell in them.
4 | $cmd = $NodePSQuery.Command
5 | if ($cmd -eq "Date")
6 | {
7 | Write-Host (Get-Date)
8 | }
9 | @"
10 | $(Write-Host Hello World Example5!)
11 |
12 |
13 |
14 | Sample Web Site Template - PoSH Server
15 |
16 |
17 |
19 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
45 |
46 |
47 |
48 |
49 |
50 |
51 |
52 |
53 |
54 |
55 |
56 |
57 |
63 |
64 |
65 |
66 |
67 |
68 |
69 |
70 |
71 |
72 |
73 |
74 |
75 |
76 |
77 |
78 |
79 |
80 |
81 |
82 |
83 |
84 |
133 |
134 |
135 |
136 |
137 |
138 |
139 |
140 |
141 | Welcome to PoSH Server! You can use Powershell commands with html codes. Let's get date: $(Get-Date)
142 |
143 |
144 |
145 |
146 |
147 |
148 |
149 |
150 |
151 |
152 |
153 |
154 |
155 |
156 |
About
157 |
158 |
159 | In the About page you can insert some information on yourself: title of study,
160 | eventual training courses attended, certificates, diplomas.
161 |
162 |
163 |
164 | Or you can describe your dreams, your work experiences... in a few words everything
165 | that can represent you on the web in a decisive and original way.
166 |
167 |
168 |
169 | Insert a small picture or even a cartoon just like the one I have inserted: nowdays illustrations are the trend!
170 |
171 |
172 |
173 |
174 |
175 |
176 |
177 |
178 |
179 |
180 |
181 |
182 |
183 |
184 |
185 |
186 |
187 |
188 |
189 |
190 |
191 |
Portfolio
192 |
193 |
194 |
195 |
196 |
197 |
198 |
I hope you like my work and my work speaks for me.
199 |
200 |
201 |
202 |
203 |
204 |
205 |
206 |
207 |
208 |
213 |
214 |
219 |
220 |
225 |
226 |
231 |
232 |
237 |
238 |
243 |
244 |
249 |
250 |
255 |
256 |
261 |
262 |
267 |
268 |
269 |
270 |
271 |
272 |
273 |
274 |
275 |
276 |
277 |
278 |
279 |
328 |
329 |
330 |
331 |
332 |
333 |
334 |
335 |
336 |
337 |
340 |
341 |
342 | "@
--------------------------------------------------------------------------------
/NodePS/Default/http/example6.ps1:
--------------------------------------------------------------------------------
1 | # You can run commands as the user who is accessing your server using "Impersonation"
2 | # Example: http://localhost:8080/example6.ps1
3 |
4 | "You are running this command as the server user $([Security.Principal.WindowsIdentity]::GetCurrent().Name) "
5 |
6 | [System.Security.Principal.WindowsImpersonationContext]$Context = $Identity.Impersonate()
7 |
8 | "You are running this command as the user accessing your site $([Security.Principal.WindowsIdentity]::GetCurrent().Name) "
9 |
10 | #Don't forget to undo the impersonation! You don't want the next guy to be executing any code as this guy.
11 | $Context.Undo()
12 |
13 | "You are running this command as as the server user $([Security.Principal.WindowsIdentity]::GetCurrent().Name) "
--------------------------------------------------------------------------------
/NodePS/Default/http/favicon.ico:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/TLaborde/NodePS/85495bd521c229286b7a3a631a4ebd64df6c640a/NodePS/Default/http/favicon.ico
--------------------------------------------------------------------------------
/NodePS/Default/http/images/add-on-skype.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/TLaborde/NodePS/85495bd521c229286b7a3a631a4ebd64df6c640a/NodePS/Default/http/images/add-on-skype.png
--------------------------------------------------------------------------------
/NodePS/Default/http/images/avatar.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/TLaborde/NodePS/85495bd521c229286b7a3a631a4ebd64df6c640a/NodePS/Default/http/images/avatar.jpg
--------------------------------------------------------------------------------
/NodePS/Default/http/images/bg/arrow1.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/TLaborde/NodePS/85495bd521c229286b7a3a631a4ebd64df6c640a/NodePS/Default/http/images/bg/arrow1.png
--------------------------------------------------------------------------------
/NodePS/Default/http/images/bg/arrow2.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/TLaborde/NodePS/85495bd521c229286b7a3a631a4ebd64df6c640a/NodePS/Default/http/images/bg/arrow2.png
--------------------------------------------------------------------------------
/NodePS/Default/http/images/bg/bottom.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/TLaborde/NodePS/85495bd521c229286b7a3a631a4ebd64df6c640a/NodePS/Default/http/images/bg/bottom.png
--------------------------------------------------------------------------------
/NodePS/Default/http/images/bg/bottom2.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/TLaborde/NodePS/85495bd521c229286b7a3a631a4ebd64df6c640a/NodePS/Default/http/images/bg/bottom2.png
--------------------------------------------------------------------------------
/NodePS/Default/http/images/bg/download.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/TLaborde/NodePS/85495bd521c229286b7a3a631a4ebd64df6c640a/NodePS/Default/http/images/bg/download.png
--------------------------------------------------------------------------------
/NodePS/Default/http/images/bg/email.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/TLaborde/NodePS/85495bd521c229286b7a3a631a4ebd64df6c640a/NodePS/Default/http/images/bg/email.png
--------------------------------------------------------------------------------
/NodePS/Default/http/images/bg/error.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/TLaborde/NodePS/85495bd521c229286b7a3a631a4ebd64df6c640a/NodePS/Default/http/images/bg/error.gif
--------------------------------------------------------------------------------
/NodePS/Default/http/images/bg/message.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/TLaborde/NodePS/85495bd521c229286b7a3a631a4ebd64df6c640a/NodePS/Default/http/images/bg/message.png
--------------------------------------------------------------------------------
/NodePS/Default/http/images/bg/name.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/TLaborde/NodePS/85495bd521c229286b7a3a631a4ebd64df6c640a/NodePS/Default/http/images/bg/name.png
--------------------------------------------------------------------------------
/NodePS/Default/http/images/bg/quote.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/TLaborde/NodePS/85495bd521c229286b7a3a631a4ebd64df6c640a/NodePS/Default/http/images/bg/quote.jpg
--------------------------------------------------------------------------------
/NodePS/Default/http/images/bg/sfere.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/TLaborde/NodePS/85495bd521c229286b7a3a631a4ebd64df6c640a/NodePS/Default/http/images/bg/sfere.jpg
--------------------------------------------------------------------------------
/NodePS/Default/http/images/bg/spinner.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/TLaborde/NodePS/85495bd521c229286b7a3a631a4ebd64df6c640a/NodePS/Default/http/images/bg/spinner.gif
--------------------------------------------------------------------------------
/NodePS/Default/http/images/bg/success.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/TLaborde/NodePS/85495bd521c229286b7a3a631a4ebd64df6c640a/NodePS/Default/http/images/bg/success.gif
--------------------------------------------------------------------------------
/NodePS/Default/http/images/bg/top-bg.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/TLaborde/NodePS/85495bd521c229286b7a3a631a4ebd64df6c640a/NodePS/Default/http/images/bg/top-bg.png
--------------------------------------------------------------------------------
/NodePS/Default/http/images/clear.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/TLaborde/NodePS/85495bd521c229286b7a3a631a4ebd64df6c640a/NodePS/Default/http/images/clear.gif
--------------------------------------------------------------------------------
/NodePS/Default/http/images/fancyzoom/bl.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/TLaborde/NodePS/85495bd521c229286b7a3a631a4ebd64df6c640a/NodePS/Default/http/images/fancyzoom/bl.gif
--------------------------------------------------------------------------------
/NodePS/Default/http/images/fancyzoom/bl.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/TLaborde/NodePS/85495bd521c229286b7a3a631a4ebd64df6c640a/NodePS/Default/http/images/fancyzoom/bl.png
--------------------------------------------------------------------------------
/NodePS/Default/http/images/fancyzoom/bm.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/TLaborde/NodePS/85495bd521c229286b7a3a631a4ebd64df6c640a/NodePS/Default/http/images/fancyzoom/bm.gif
--------------------------------------------------------------------------------
/NodePS/Default/http/images/fancyzoom/bm.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/TLaborde/NodePS/85495bd521c229286b7a3a631a4ebd64df6c640a/NodePS/Default/http/images/fancyzoom/bm.png
--------------------------------------------------------------------------------
/NodePS/Default/http/images/fancyzoom/br.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/TLaborde/NodePS/85495bd521c229286b7a3a631a4ebd64df6c640a/NodePS/Default/http/images/fancyzoom/br.gif
--------------------------------------------------------------------------------
/NodePS/Default/http/images/fancyzoom/br.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/TLaborde/NodePS/85495bd521c229286b7a3a631a4ebd64df6c640a/NodePS/Default/http/images/fancyzoom/br.png
--------------------------------------------------------------------------------
/NodePS/Default/http/images/fancyzoom/closebox.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/TLaborde/NodePS/85495bd521c229286b7a3a631a4ebd64df6c640a/NodePS/Default/http/images/fancyzoom/closebox.gif
--------------------------------------------------------------------------------
/NodePS/Default/http/images/fancyzoom/closebox.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/TLaborde/NodePS/85495bd521c229286b7a3a631a4ebd64df6c640a/NodePS/Default/http/images/fancyzoom/closebox.png
--------------------------------------------------------------------------------
/NodePS/Default/http/images/fancyzoom/loading.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/TLaborde/NodePS/85495bd521c229286b7a3a631a4ebd64df6c640a/NodePS/Default/http/images/fancyzoom/loading.gif
--------------------------------------------------------------------------------
/NodePS/Default/http/images/fancyzoom/ml.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/TLaborde/NodePS/85495bd521c229286b7a3a631a4ebd64df6c640a/NodePS/Default/http/images/fancyzoom/ml.gif
--------------------------------------------------------------------------------
/NodePS/Default/http/images/fancyzoom/ml.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/TLaborde/NodePS/85495bd521c229286b7a3a631a4ebd64df6c640a/NodePS/Default/http/images/fancyzoom/ml.png
--------------------------------------------------------------------------------
/NodePS/Default/http/images/fancyzoom/mr.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/TLaborde/NodePS/85495bd521c229286b7a3a631a4ebd64df6c640a/NodePS/Default/http/images/fancyzoom/mr.gif
--------------------------------------------------------------------------------
/NodePS/Default/http/images/fancyzoom/mr.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/TLaborde/NodePS/85495bd521c229286b7a3a631a4ebd64df6c640a/NodePS/Default/http/images/fancyzoom/mr.png
--------------------------------------------------------------------------------
/NodePS/Default/http/images/fancyzoom/tl.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/TLaborde/NodePS/85495bd521c229286b7a3a631a4ebd64df6c640a/NodePS/Default/http/images/fancyzoom/tl.gif
--------------------------------------------------------------------------------
/NodePS/Default/http/images/fancyzoom/tl.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/TLaborde/NodePS/85495bd521c229286b7a3a631a4ebd64df6c640a/NodePS/Default/http/images/fancyzoom/tl.png
--------------------------------------------------------------------------------
/NodePS/Default/http/images/fancyzoom/tm.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/TLaborde/NodePS/85495bd521c229286b7a3a631a4ebd64df6c640a/NodePS/Default/http/images/fancyzoom/tm.gif
--------------------------------------------------------------------------------
/NodePS/Default/http/images/fancyzoom/tm.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/TLaborde/NodePS/85495bd521c229286b7a3a631a4ebd64df6c640a/NodePS/Default/http/images/fancyzoom/tm.png
--------------------------------------------------------------------------------
/NodePS/Default/http/images/fancyzoom/tr.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/TLaborde/NodePS/85495bd521c229286b7a3a631a4ebd64df6c640a/NodePS/Default/http/images/fancyzoom/tr.gif
--------------------------------------------------------------------------------
/NodePS/Default/http/images/fancyzoom/tr.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/TLaborde/NodePS/85495bd521c229286b7a3a631a4ebd64df6c640a/NodePS/Default/http/images/fancyzoom/tr.png
--------------------------------------------------------------------------------
/NodePS/Default/http/images/follow-me.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/TLaborde/NodePS/85495bd521c229286b7a3a631a4ebd64df6c640a/NodePS/Default/http/images/follow-me.gif
--------------------------------------------------------------------------------
/NodePS/Default/http/images/logo.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/TLaborde/NodePS/85495bd521c229286b7a3a631a4ebd64df6c640a/NodePS/Default/http/images/logo.png
--------------------------------------------------------------------------------
/NodePS/Default/http/images/logo.small.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/TLaborde/NodePS/85495bd521c229286b7a3a631a4ebd64df6c640a/NodePS/Default/http/images/logo.small.gif
--------------------------------------------------------------------------------
/NodePS/Default/http/images/portfolio/001.big.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/TLaborde/NodePS/85495bd521c229286b7a3a631a4ebd64df6c640a/NodePS/Default/http/images/portfolio/001.big.jpg
--------------------------------------------------------------------------------
/NodePS/Default/http/images/portfolio/002.big.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/TLaborde/NodePS/85495bd521c229286b7a3a631a4ebd64df6c640a/NodePS/Default/http/images/portfolio/002.big.jpg
--------------------------------------------------------------------------------
/NodePS/Default/http/images/portfolio/003.big.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/TLaborde/NodePS/85495bd521c229286b7a3a631a4ebd64df6c640a/NodePS/Default/http/images/portfolio/003.big.jpg
--------------------------------------------------------------------------------
/NodePS/Default/http/images/portfolio/004.big.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/TLaborde/NodePS/85495bd521c229286b7a3a631a4ebd64df6c640a/NodePS/Default/http/images/portfolio/004.big.jpg
--------------------------------------------------------------------------------
/NodePS/Default/http/images/portfolio/005.big.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/TLaborde/NodePS/85495bd521c229286b7a3a631a4ebd64df6c640a/NodePS/Default/http/images/portfolio/005.big.jpg
--------------------------------------------------------------------------------
/NodePS/Default/http/images/portfolio/006.big.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/TLaborde/NodePS/85495bd521c229286b7a3a631a4ebd64df6c640a/NodePS/Default/http/images/portfolio/006.big.jpg
--------------------------------------------------------------------------------
/NodePS/Default/http/images/send-mail.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/TLaborde/NodePS/85495bd521c229286b7a3a631a4ebd64df6c640a/NodePS/Default/http/images/send-mail.gif
--------------------------------------------------------------------------------
/NodePS/Default/http/index.htm:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | Sample Web Site Template - PoSH Server
5 |
6 |
7 |
9 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
35 |
36 |
37 |
38 |
39 |
40 |
41 |
42 |
43 |
44 |
45 |
46 |
47 |
53 |
54 |
55 |
56 |
57 |
58 |
59 |
60 |
61 |
62 |
63 |
64 |
65 |
66 |
67 |
68 |
69 |
70 |
71 |
72 |
73 |
74 |
123 |
124 |
125 |
126 |
127 |
128 |
129 |
130 |
131 | Welcome to PoSH Server! You can use Powershell commands with html codes. Let's get date: $(Get-Date)
132 |
133 |
134 |
135 |
136 |
137 |
138 |
139 |
140 |
141 |
142 |
143 |
144 |
145 |
146 |
About
147 |
148 |
149 | In the About page you can insert some information on yourself: title of study,
150 | eventual training courses attended, certificates, diplomas.
151 |
152 |
153 |
154 | Or you can describe your dreams, your work experiences... in a few words everything
155 | that can represent you on the web in a decisive and original way.
156 |
157 |
158 |
159 | Insert a small picture or even a cartoon just like the one I have inserted: nowdays illustrations are the trend!
160 |
161 |
162 |
163 |
164 |
165 |
166 |
167 |
168 |
169 |
170 |
171 |
172 |
173 |
174 |
175 |
176 |
177 |
178 |
179 |
180 |
181 |
Portfolio
182 |
183 |
184 |
185 |
186 |
187 |
188 |
I hope you like my work and my work speaks for me.
189 |
190 |
191 |
192 |
193 |
194 |
195 |
196 |
197 |
198 |
203 |
204 |
209 |
210 |
215 |
216 |
221 |
222 |
227 |
228 |
233 |
234 |
239 |
240 |
245 |
246 |
251 |
252 |
257 |
258 |
259 |
260 |
261 |
262 |
263 |
264 |
265 |
266 |
267 |
268 |
269 |
318 |
319 |
320 |
321 |
322 |
323 |
324 |
325 |
326 |
327 |
330 |
331 |
--------------------------------------------------------------------------------
/NodePS/Default/http/index.ps1:
--------------------------------------------------------------------------------
1 | @"
2 |
3 |
4 |
5 | Sample Web Site Template - PoSH Server
6 |
7 |
8 |
10 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
36 |
37 |
38 |
39 |
40 |
41 |
42 |
43 |
44 |
45 |
46 |
47 |
48 |
54 |
55 |
56 |
57 |
58 |
59 |
60 |
61 |
62 |
63 |
64 |
65 |
66 |
67 |
68 |
69 |
70 |
71 |
72 |
73 |
74 |
75 |
124 |
125 |
126 |
127 |
128 |
129 |
130 |
131 |
132 | Welcome to PoSH Server! You can use Powershell commands with html codes. Let's get date: $(Get-Date)
133 |
134 |
135 |
136 |
137 |
138 |
139 |
140 |
141 |
142 |
143 |
144 |
145 |
146 |
147 |
About
148 |
149 |
150 | In the About page you can insert some information on yourself: title of study,
151 | eventual training courses attended, certificates, diplomas.
152 |
153 |
154 |
155 | Or you can describe your dreams, your work experiences... in a few words everything
156 | that can represent you on the web in a decisive and original way.
157 |
158 |
159 |
160 | Insert a small picture or even a cartoon just like the one I have inserted: nowdays illustrations are the trend!
161 |
162 |
163 |
164 |
165 |
166 |
167 |
168 |
169 |
170 |
171 |
172 |
173 |
174 |
175 |
176 |
177 |
178 |
179 |
180 |
181 |
182 |
Portfolio
183 |
184 |
185 |
186 |
187 |
188 |
189 |
I hope you like my work and my work speaks for me.
190 |
191 |
192 |
193 |
194 |
195 |
196 |
197 |
198 |
199 |
204 |
205 |
210 |
211 |
216 |
217 |
222 |
223 |
228 |
229 |
234 |
235 |
240 |
241 |
246 |
247 |
252 |
253 |
258 |
259 |
260 |
261 |
262 |
263 |
264 |
265 |
266 |
267 |
268 |
269 |
270 |
319 |
320 |
321 |
322 |
323 |
324 |
325 |
326 |
327 |
328 |
331 |
332 |
333 | "@
--------------------------------------------------------------------------------
/NodePS/Default/http/js/cufon-yui.js:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) 2009 Simo Kinnunen.
3 | * Licensed under the MIT license.
4 | *
5 | * @version 1.09i
6 | */
7 | var Cufon=(function(){var m=function(){return m.replace.apply(null,arguments)};var x=m.DOM={ready:(function(){var C=false,E={loaded:1,complete:1};var B=[],D=function(){if(C){return}C=true;for(var F;F=B.shift();F()){}};if(document.addEventListener){document.addEventListener("DOMContentLoaded",D,false);window.addEventListener("pageshow",D,false)}if(!window.opera&&document.readyState){(function(){E[document.readyState]?D():setTimeout(arguments.callee,10)})()}if(document.readyState&&document.createStyleSheet){(function(){try{document.body.doScroll("left");D()}catch(F){setTimeout(arguments.callee,1)}})()}q(window,"load",D);return function(F){if(!arguments.length){D()}else{C?F():B.push(F)}}})(),root:function(){return document.documentElement||document.body}};var n=m.CSS={Size:function(C,B){this.value=parseFloat(C);this.unit=String(C).match(/[a-z%]*$/)[0]||"px";this.convert=function(D){return D/B*this.value};this.convertFrom=function(D){return D/this.value*B};this.toString=function(){return this.value+this.unit}},addClass:function(C,B){var D=C.className;C.className=D+(D&&" ")+B;return C},color:j(function(C){var B={};B.color=C.replace(/^rgba\((.*?),\s*([\d.]+)\)/,function(E,D,F){B.opacity=parseFloat(F);return"rgb("+D+")"});return B}),fontStretch:j(function(B){if(typeof B=="number"){return B}if(/%$/.test(B)){return parseFloat(B)/100}return{"ultra-condensed":0.5,"extra-condensed":0.625,condensed:0.75,"semi-condensed":0.875,"semi-expanded":1.125,expanded:1.25,"extra-expanded":1.5,"ultra-expanded":2}[B]||1}),getStyle:function(C){var B=document.defaultView;if(B&&B.getComputedStyle){return new a(B.getComputedStyle(C,null))}if(C.currentStyle){return new a(C.currentStyle)}return new a(C.style)},gradient:j(function(F){var G={id:F,type:F.match(/^-([a-z]+)-gradient\(/)[1],stops:[]},C=F.substr(F.indexOf("(")).match(/([\d.]+=)?(#[a-f0-9]+|[a-z]+\(.*?\)|[a-z]+)/ig);for(var E=0,B=C.length,D;E0){E=" "+E}}else{if(B400}if(I==500){I=400}for(var J in G){if(!k(G,J)){continue}J=parseInt(J,10);if(!F||JD){D=J}K.push(J)}if(ID){I=D}K.sort(function(M,L){return(E?(M>=I&&L>=I)?ML:(M<=I&&L<=I)?M>L:Mcufoncanvas{text-indent:0;}@media screen{cvml\\:shape,cvml\\:rect,cvml\\:fill,cvml\\:shadow{behavior:url(#default#VML);display:block;antialias:true;position:absolute;}cufoncanvas{position:absolute;text-align:left;}cufon{display:inline-block;position:relative;vertical-align:'+(h?"middle":"text-bottom")+";}cufon cufontext{position:absolute;left:-10000in;font-size:1px;}a cufon{cursor:pointer}}@media print{cufon cufoncanvas{display:none;}}").replace(/;/g,"!important;"));function c(i,j){return a(i,/(?:em|ex|%)$|^[a-z-]+$/i.test(j)?"1em":j)}function a(l,m){if(m==="0"){return 0}if(/px$/i.test(m)){return parseFloat(m)}var k=l.style.left,j=l.runtimeStyle.left;l.runtimeStyle.left=l.currentStyle.left;l.style.left=m.replace("%","em");var i=l.style.pixelLeft;l.style.left=k;l.runtimeStyle.left=j;return i}function f(l,k,j,n){var i="computed"+n,m=k[i];if(isNaN(m)){m=k.get(n);k[i]=m=(m=="normal")?0:~~j.convertFrom(a(l,m))}return m}var g={};function d(p){var q=p.id;if(!g[q]){var n=p.stops,o=document.createElement("cvml:fill"),i=[];o.type="gradient";o.angle=180;o.focus="0";o.method="sigma";o.color=n[0][1];for(var m=1,l=n.length-1;mO){O=K}if(I>N){N=I}if(K0){E=" "+E}}else{if(B400}if(I==500){I=400}for(var J in G){if(!k(G,J)){continue}J=parseInt(J,10);if(!F||JD){D=J}K.push(J)}if(ID){I=D}K.sort(function(M,L){return(E?(M>=I&&L>=I)?ML:(M<=I&&L<=I)?M>L:MO){O=K}if(I>N){N=I}if(Kcufoncanvas{text-indent:0;}@media screen{cvml\\:shape,cvml\\:rect,cvml\\:fill,cvml\\:shadow{behavior:url(#default#VML);display:block;antialias:true;position:absolute;}cufoncanvas{position:absolute;text-align:left;}cufon{display:inline-block;position:relative;vertical-align:'+(h?"middle":"text-bottom")+";}cufon cufontext{position:absolute;left:-10000in;font-size:1px;}a cufon{cursor:pointer}}@media print{cufon cufoncanvas{display:none;}}").replace(/;/g,"!important;"));function c(i,j){return a(i,/(?:em|ex|%)$|^[a-z-]+$/i.test(j)?"1em":j)}function a(l,m){if(m==="0"){return 0}if(/px$/i.test(m)){return parseFloat(m)}var k=l.style.left,j=l.runtimeStyle.left;l.runtimeStyle.left=l.currentStyle.left;l.style.left=m.replace("%","em");var i=l.style.pixelLeft;l.style.left=k;l.runtimeStyle.left=j;return i}function f(l,k,j,n){var i="computed"+n,m=k[i];if(isNaN(m)){m=k.get(n);k[i]=m=(m=="normal")?0:~~j.convertFrom(a(l,m))}return m}var g={};function d(p){var q=p.id;if(!g[q]){var n=p.stops,o=document.createElement("cvml:fill"),i=[];o.type="gradient";o.angle=180;o.focus="0";o.method="sigma";o.color=n[0][1];for(var m=1,l=n.length-1;m \
33 | \
34 | \
35 | \
36 | \
37 | \
38 | \
39 | \
40 |
\
41 | \
42 | \
43 | \
44 | \
45 | \
46 | \
47 | \
48 | \
49 | \
50 | \
51 | \
52 | \
53 | ';
54 | $(document.body).grab(new Element('div', {id:"zoom", style:"display:none;z-index:200;", html: html}));
55 | //Setup the FX as class methods
56 | FancyZoom.showFx = new Fx.Morph($('zoom'), {
57 | link: 'cancel',
58 | onStart: function(element) {
59 | var fancy = element.retrieve('fancy')
60 | if(fancy.options.scaleImg) {
61 | fancy.content_div.getElements('img').setStyles({'width': 50, 'height':'auto'})
62 | $('zoom_content').set('html', fancy.content_div.get('html'));
63 | //This is still broken in IE
64 | $$('#zoom_content img').tween('width', this.to.width[0].value - 60)
65 | } else
66 | $('zoom_content').set('html','');
67 | },
68 | onComplete: function(element) {
69 | FancyZoom.zoomed = true;
70 | var fancy = element.retrieve('fancy')
71 | fancy.loaded = false
72 | if (!fancy.options.scaleImg)
73 | $('zoom_content').set('html', fancy.content_div.get('html'));
74 | // middle row height must be set for IE otherwise it tries to be "logical" with the height
75 | if(Browser.Engine.trident)
76 | $$('td.ml, td.mm, td.mr').setStyle('height', this.to.height[0].value - 60);
77 | $('zoom_close').setStyle('display', '');
78 | FancyZoom.unfixBackgroundsForIE();
79 | }
80 | })
81 | FancyZoom.hideFx = new Fx.Morph($('zoom'), {
82 | onStart: function(element) {
83 | if (!element.retrieve('fancy').scaleImg)
84 | $('zoom_content').set({'html': '', 'style':''})
85 | $('zoom_close').setStyle('display', 'none');
86 | },
87 | onComplete: function(element) {
88 | FancyZoom.zoomed = false;
89 | element.setStyle('display', 'none');
90 | FancyZoom.unfixBackgroundsForIE();
91 | }
92 | })
93 | //Attach the events only once
94 | $('zoom_close').addEvent('click', FancyZoom.hide);
95 | // hide zoom if click fired is not inside zoom
96 | $$('html')[0].addEvent('click', function(e) {
97 | if (!($(e.target).match('#zoom') || $(e.target).getParent('#zoom')))
98 | FancyZoom.hide(e);
99 | });
100 | // esc to close zoom box
101 | $(document).addEvent('keyup', function(e) {
102 | if (e.key == 'esc')
103 | FancyZoom.hide(e);
104 | });
105 | }
106 | });
107 | FancyZoom.zoomed = false;
108 | FancyZoom.show = function(e) {
109 | e.stop();
110 | var element = $(e.target).match('a') ? e.target : e.target.getParent('a');
111 | var fancy = element.retrieve('fancy')
112 | var width = (fancy.options.width || fancy.content_div.getWidth()) + 60;
113 | var height = (fancy.options.height || fancy.content_div.getHeight()) + 60;
114 | //Make the image a maximum of 1024px wide
115 | var height = (Math.min(fancy.options.max, width) / width) * height
116 | var width = Math.min(fancy.options.max, width)
117 | var d = Window.getSize();
118 | var yOffset = Window.getScrollTop();
119 | // ensure that newTop is at least 0 so it doesn't hide close button
120 | var newTop = Math.max((d.y/2) - (height/2) + yOffset, 0);
121 | var newLeft = (d.x/2) - (width/2);
122 | if(!fancy.loaded) {
123 | $('zoom').store('curTop', e.page.y);
124 | $('zoom').store('curLeft', e.page.x);
125 | $('zoom').store('fancy', fancy);
126 | $('zoom').setStyles({
127 | position : 'absolute',
128 | display : 'block',
129 | opacity : 0,
130 | top : e.page.y,
131 | left : e.page.x,
132 | width : 1,
133 | height : 1
134 | });
135 | //So we need a delay for IE to be happy....
136 | fancy.fireEvent('show', {stop:$empty, target:element, page: e.page}, 100)
137 | }
138 | FancyZoom.fixBackgroundsForIE();
139 | FancyZoom.showFx.start({
140 | opacity: 1,
141 | top: newTop,
142 | left: newLeft,
143 | width: width,
144 | height: height})
145 | }
146 | FancyZoom.hide = function(e) {
147 | if(!FancyZoom.zoomed)
148 | return
149 | e.stop();
150 | $('zoom').retrieve('fancy').fireEvent('hide')
151 | FancyZoom.fixBackgroundsForIE();
152 | FancyZoom.hideFx.start({
153 | left: $('zoom').retrieve('curLeft'),
154 | top: $('zoom').retrieve('curTop'),
155 | width: 1,
156 | height: 1,
157 | opacity: 0});
158 | }
159 | FancyZoom.switchBackgroundImagesTo = function(to) {
160 | $$('#zoom_table td').each(function(e) {
161 | var bg = e.getStyle('background-image').replace(/\.(png|gif|none)\)$/, '.'+to+')');
162 | e.setStyle('background-image', bg);
163 | });
164 | var close_img = zoom_close.getElement('img');
165 | var new_img = close_img.get('src').replace(/\.(png|gif|none)$/, '.' + to);
166 | close_img.set('src', new_img);
167 | }
168 | FancyZoom.fixBackgroundsForIE = function() {
169 | if (Browser.Engine.trident5) {
170 | FancyZoom.switchBackgroundImagesTo('gif');
171 | }
172 | }
173 | FancyZoom.unfixBackgroundsForIE = function() {
174 | if (Browser.Engine.trident5) {
175 | FancyZoom.switchBackgroundImagesTo('png');
176 | }
177 | }
--------------------------------------------------------------------------------
/NodePS/Default/http/js/form-contact-validate.js:
--------------------------------------------------------------------------------
1 | jQuery(document).ready(function(){
2 |
3 | jQuery(" ")
4 | .attr("src","http://www.yourinspirationweb.com/wp-content/themes/yiw/images/clear.gif")
5 | .prependTo('body');
6 |
7 | jQuery('
')
8 | .insertBefore('#log')
9 | .attr('id','log_wait')
10 | .css('display','none')
11 | .addClass('ajax-loading')
12 | .ajaxStart(function(){jQuery(this).show();})
13 | .ajaxStop(function(){jQuery(this).hide();});
14 |
15 |
16 | jQuery('#contacts').submit(function() {
17 | jQuery.post('include/inc_sendmail.php',jQuery(this).serialize(), function(data){
18 | jQuery('#log').empty();
19 | jQuery('
')
20 | .attr('id','log_res')
21 | .appendTo('#log')
22 | .html(data);
23 | });
24 | return false;
25 | });
26 | });
--------------------------------------------------------------------------------
/NodePS/Default/http/js/scroll.js:
--------------------------------------------------------------------------------
1 | jQuery(document).ready(function(){
2 | jQuery('#nav a[href*=#]').click(function() {
3 | if (location.pathname.replace(/^\//,'') == this.pathname.replace(/^\//,'')
4 | && location.hostname == this.hostname) {
5 | var $target = jQuery(this.hash);
6 | $target = $target.length && $target
7 | || $('[name=' + this.hash.slice(1) +']');
8 | if ($target.length) {
9 | var targetOffset = $target.offset().top;
10 | jQuery('html,body')
11 | .animate({scrollTop: targetOffset}, 1000);
12 | return false;
13 | }
14 | }
15 | });
16 | });
17 |
--------------------------------------------------------------------------------
/NodePS/Default/http/js/unitpngfix.js:
--------------------------------------------------------------------------------
1 | //var clear="wp-content/themes/eclectic/images/clear.gif" //path to clear.gif
2 |
3 | pngfix=function(){var els=document.getElementsByTagName('*');var ip=/\.png/i;var i=els.length;while(i-- >0){var el=els[i];var es=el.style;if(el.src&&el.src.match(ip)&&!es.filter){es.height=el.height;es.width=el.width;es.filter="progid:DXImageTransform.Microsoft.AlphaImageLoader(src='"+el.src+"',sizingMethod='crop')";el.src=clear;}else{var elb=el.currentStyle.backgroundImage;if(elb.match(ip)){var path=elb.split('"');var rep=(el.currentStyle.backgroundRepeat=='no-repeat')?'crop':'scale';es.filter="progid:DXImageTransform.Microsoft.AlphaImageLoader(src='"+path[1]+"',sizingMethod='"+rep+"')";es.height=el.clientHeight+'px';es.backgroundImage='none';var elkids=el.getElementsByTagName('*');if (elkids){var j=elkids.length;if(el.currentStyle.position!="absolute")es.position='static';while (j-- >0)if(!elkids[j].style.position)elkids[j].style.position="relative";}}}}}
4 | window.attachEvent('onload',pngfix);
--------------------------------------------------------------------------------
/NodePS/NodePS.psd1:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/TLaborde/NodePS/85495bd521c229286b7a3a631a4ebd64df6c640a/NodePS/NodePS.psd1
--------------------------------------------------------------------------------
/NodePS/NodePS.psm1:
--------------------------------------------------------------------------------
1 | #Get public and private function definition files.
2 | $Public = @(Get-ChildItem -Path $PSScriptRoot\Public\*.ps1 -ErrorAction SilentlyContinue)
3 | $Private = @(Get-ChildItem -Path $PSScriptRoot\Private\*.ps1 -ErrorAction SilentlyContinue)
4 |
5 | #Dot source the files
6 | foreach ($import in @($Public + $Private)) {
7 | try {
8 | . $import.fullname
9 | } catch {
10 | Write-Error -Message "Failed to import function $($import.fullname): $_"
11 | }
12 | }
13 | Export-ModuleMember -Function $Public.Basename
--------------------------------------------------------------------------------
/NodePS/Private/Get-404PageContent.ps1:
--------------------------------------------------------------------------------
1 | # NodePS Server 404 Module
2 | function Get-404PageContent {
3 | param (
4 | [Parameter(
5 | Mandatory = $true)]
6 | $Hostname
7 | )
8 | if ($Hostname -eq "+") { $HeaderName = "localhost" } else { $HeaderName = $Hostnames[0] }
9 | @"
10 |
11 |
12 |
13 | NodePS Server - 404.0 - Not Found
14 |
57 |
58 |
59 |
60 |
61 | NodePS Server Microsoft-HTTPAPI/2.0
62 |
63 |
64 |
Error Summary
65 | HTTP Error 404.0 - Not Found
66 | The resource you are looking for has been removed, had its name changed, or is temporarily unavailable.
67 |
68 |
69 |
70 |
Most likely causes:
71 | The directory or file specified does not exist on the Web server. The URL contains a typographical error. A custom filter or module, such as URLScan, restricts access to the file.
72 |
73 |
74 |
75 |
Things you can try:
76 | Create the content on the Web server. Review the browser URL. Create a tracing rule to track failed requests for this HTTP status code and see which module is calling SetStatus. For more information about creating a tracing rule for failed requests, click here .
77 |
78 |
79 |
80 |
81 |
82 |
Links and More Information
83 | This error means that the file or directory does not exist on the server. Create the file or directory and try the request again.
84 | View more information »
85 |
86 |
87 |
88 |
89 |
90 |
91 | "@
92 | }
93 |
--------------------------------------------------------------------------------
/NodePS/Private/Get-Authentication.ps1:
--------------------------------------------------------------------------------
1 | # NodePS Server Authentication Module
2 | function Get-Authentication {
3 | param (
4 | [Parameter(
5 | Mandatory = $true)]
6 | $Context,
7 |
8 | [Parameter(
9 | Mandatory = $true)]
10 | $BasicAuthentication,
11 |
12 | [Parameter(
13 | Mandatory = $true)]
14 | $WindowsAuthentication
15 | )
16 | # Basic Authentication
17 |
18 | if ($BasicAuthentication -eq "On") {
19 | $Identity = $Context.User.Identity
20 | $NodePSUserName = $Identity.Name
21 | $NodePSUserPassword = $Identity.Password
22 | }
23 |
24 | # Windows Authentication
25 | if ($WindowsAuthentication -eq "On") {
26 | $Identity = $Context.User.Identity
27 | $NodePSUserName = $Identity.Name
28 | $NodePSUserPassword = ""
29 | }
30 |
31 | @($Identity,$NodePSUserName,$NodePSUserPassword)
32 | }
33 |
34 |
--------------------------------------------------------------------------------
/NodePS/Private/Get-DirectoryContent.ps1:
--------------------------------------------------------------------------------
1 | function Get-DirectoryContent {
2 |
3 | <#
4 | .SYNOPSIS
5 |
6 | Function to get directory content
7 |
8 | .EXAMPLE
9 |
10 | Get-DirectoryContent -Path "C:\" -HeaderName "NodePSserver.net" -RequestURL "http://NodePSserver.net" -SubfolderName "/"
11 |
12 | #>
13 |
14 | [CmdletBinding(SupportsShouldProcess = $true)]
15 | param (
16 |
17 | [Parameter(
18 | Mandatory = $true,
19 | HelpMessage = 'Directory Path')]
20 | [string]$Path,
21 |
22 | [Parameter(
23 | Mandatory = $false,
24 | HelpMessage = 'Header Name')]
25 | [string]$HeaderName,
26 |
27 | [Parameter(
28 | Mandatory = $false,
29 | HelpMessage = 'Request URL')]
30 | [string]$RequestURL,
31 |
32 | [Parameter(
33 | Mandatory = $false,
34 | HelpMessage = 'Subfolder Name')]
35 | [string]$SubfolderName
36 | )
37 |
38 | @"
39 |
40 |
41 | $($HeaderName)
42 |
43 |
44 | $($HeaderName) - $($SubfolderName)
45 |
46 | "@
47 |
48 | $ParentDirectory = $RequestURL + $Subfoldername + "../"
49 |
50 | @"
51 | [To Parent Directory]
52 |
53 | "@
54 |
55 | $Files = (Get-ChildItem "$Path")
56 | foreach ($File in $Files) {
57 | $FileURL = $RequestURL + $Subfoldername + $File.Name
58 | if (!$File.Length) {
59 | $FileLength = "[dir]"
60 | } else {
61 | $FileLength = $File.Length
62 | }
63 | @"
64 |
65 | $($File.LastWriteTime)
66 | $($FileLength)
67 | $($File.Name)
68 |
69 | "@
70 | }
71 | @"
72 |
73 |
74 |
75 |
76 | "@
77 | }
78 |
79 |
--------------------------------------------------------------------------------
/NodePS/Private/Get-MimeType.ps1:
--------------------------------------------------------------------------------
1 | function Get-MimeType {
2 |
3 | <#
4 | .SYNOPSIS
5 |
6 | Function to get mime types
7 |
8 | .EXAMPLE
9 |
10 | Get-MimeType -Extension ".jpg"
11 |
12 | #>
13 |
14 | [CmdletBinding(SupportsShouldProcess = $true)]
15 | param (
16 |
17 | [Parameter(
18 | Mandatory = $false,
19 | HelpMessage = 'Extension')]
20 | [string]$Extension
21 | )
22 |
23 | switch ($Extension) {
24 | .ps1 {"text/ps1"}
25 | .psjson {"text/psjson"}
26 | .psxml {"text/psxml"}
27 | .html {"text/html"}
28 | .htm {"text/html"}
29 | .css {"text/css"}
30 | .jpeg {"image/jpeg"}
31 | .jpg {"image/jpeg"}
32 | .gif {"image/gif"}
33 | .ico {"image/x-icon"}
34 | .flv {"video/x-flv"}
35 | .swf {"application/x-shockwave-flash"}
36 | .js {"text/javascript"}
37 | .txt {"text/plain"}
38 | .rar {"application/octet-stream"}
39 | .zip {"application/x-zip-compressed"}
40 | .rss {"application/rss+xml"}
41 | .xml {"text/xml"}
42 | .pdf {"application/pdf"}
43 | .png {"image/png"}
44 | .mpg {"video/mpeg"}
45 | .mpeg {"video/mpeg"}
46 | .mp3 {"audio/mpeg"}
47 | .oga {"audio/ogg"}
48 | .spx {"audio/ogg"}
49 | .mp4 {"video/mp4"}
50 | .m4v {"video/m4v"}
51 | .ogg {"video/ogg"}
52 | .ogv {"video/ogg"}
53 | .webm {"video/webm"}
54 | .wmv {"video/x-ms-wmv"}
55 | .woff {"application/x-font-woff"}
56 | .eot {"application/vnd.ms-fontobject"}
57 | .svg {"image/svg+xml"}
58 | .svgz {"image/svg+xml"}
59 | .otf {"font/otf"}
60 | .ttf {"application/x-font-ttf"}
61 | .xht {"application/xhtml+xml"}
62 | .xhtml {"application/xhtml+xml"}
63 | default {"text/html"}
64 | }
65 | }
66 |
67 |
--------------------------------------------------------------------------------
/NodePS/Private/Get-NodePSPostStream.ps1:
--------------------------------------------------------------------------------
1 | function Get-NodePSPostStream {
2 |
3 | <#
4 | .SYNOPSIS
5 |
6 | Function to get php post stream
7 |
8 | .EXAMPLE
9 |
10 | Get-NodePSPostStream -InputStream $InputStream -ContentEncoding $ContentEncoding
11 |
12 | #>
13 |
14 | [CmdletBinding(SupportsShouldProcess = $true)]
15 | param (
16 | [Parameter(
17 | Mandatory = $true,
18 | HelpMessage = 'Input Stream')]
19 | $InputStream,
20 |
21 | [Parameter(
22 | Mandatory = $true,
23 | HelpMessage = 'Content Encoding')]
24 | $ContentEncoding,
25 |
26 | [Parameter(
27 | Mandatory = $false,
28 | HelpMessage = 'Content Type')]
29 | $ContentType
30 | )
31 |
32 | $NodePSPostStream = New-Object IO.StreamReader ($InputStream,$ContentEncoding)
33 | $NodePSPostStream = $NodePSPostStream.ReadToEnd()
34 | $NodePSPostStream = $NodePSPostStream.ToString()
35 |
36 | if ($NodePSPostStream) {
37 | $Properties = New-Object Psobject
38 |
39 | if ($ContentType -eq "application/json") {
40 | $Properties = $NodePSPostStream | ConvertFrom-Json
41 | } else {
42 | $NodePSCommand = $NodePSPostStream -Split "&"
43 | foreach ($Post in $NodePSCommand) {
44 | $PostContent = $Post -Split "="
45 | [System.Reflection.Assembly]::LoadWithPartialName("System.Web") | out-null
46 | $PostName = [System.Web.HttpUtility]::UrlDecode($PostContent[0])
47 | $PostValue = [System.Web.HttpUtility]::UrlDecode($PostContent[1])
48 |
49 | if ($PostName.EndsWith("[]")) {
50 | $PostName = $PostName.Substring(0,$PostName.Length-2)
51 |
52 | if (!(New-Object PSObject -Property @{PostName=@()}).PostName) {
53 | $Properties | Add-Member NoteProperty $Postname (@())
54 | $Properties."$PostName" += $PostValue
55 | } else {
56 | $Properties."$PostName" += $PostValue
57 | }
58 | } else {
59 | $Properties | Add-Member NoteProperty $PostName $PostValue
60 | }
61 | }
62 | }
63 | $Properties | Add-Member Noteproperty NodePSPostStream $NodePSPostStream
64 | $Properties | Add-Member Noteproperty NodePSContentType $ContentType
65 | Write-Output $Properties
66 | }
67 | }
68 |
--------------------------------------------------------------------------------
/NodePS/Private/Get-NodePSQueryString.ps1:
--------------------------------------------------------------------------------
1 | function Get-NodePSQueryString {
2 |
3 | <#
4 | .SYNOPSIS
5 |
6 | Function to get query string
7 |
8 | .EXAMPLE
9 |
10 | Get-NodePSQueryString -Request $Request
11 |
12 | #>
13 |
14 | [CmdletBinding(SupportsShouldProcess = $true)]
15 | param (
16 |
17 | [Parameter(
18 | Mandatory = $false,
19 | HelpMessage = 'Request')]
20 | $Request
21 | )
22 |
23 | if ($Request) {
24 | $NodePSQueryString = $Request.RawUrl.Split("?")[1]
25 | $QueryStrings = $Request.QueryString
26 |
27 | $Properties = New-Object Psobject
28 | $Properties | Add-Member Noteproperty NodePSQueryString $NodePSQueryString
29 | foreach ($Query in $QueryStrings) {
30 | $QueryString = $Request.QueryString["$Query"]
31 | if ($QueryString -and $Query) {
32 | $Properties | Add-Member Noteproperty $Query $QueryString
33 | }
34 | }
35 | Write-Output $Properties
36 | }
37 | }
38 |
39 |
--------------------------------------------------------------------------------
/NodePS/Private/Get-NodePSThreadScriptBlock.ps1:
--------------------------------------------------------------------------------
1 | function Get-NodePSThreadScriptBlock {
2 |
3 | return {
4 | Param($Listener, $Hostname, $HomeDirectory, $LogDirectory, $NodePSModulePath, $ThreadConfig, $SharedData)
5 | # we need to load the private function manually...
6 | Get-ChildItem $NodePSModulePath\Private\*.ps1 -Recurse | ForEach-Object {. $_.FullName }
7 |
8 | . $ThreadConfig
9 |
10 | # Set Home Directory
11 | [IO.Directory]::SetCurrentDirectory("$HomeDirectory")
12 |
13 | # Get Server Requests
14 | while ($Listener.IsListening) {
15 | # Set Default Authentication
16 | $Listener.AuthenticationSchemes = "Anonymous";
17 |
18 | # Set Authentication
19 | if ($BasicAuthentication -eq "On") { $Listener.AuthenticationSchemes = "Basic"; }
20 | if ($NTLMAuthentication -eq "On") { $Listener.AuthenticationSchemes = "NTLM"; }
21 | if ($WindowsAuthentication -eq "On") { $Listener.AuthenticationSchemes = "IntegratedWindowsAuthentication"; }
22 |
23 | # Open Connection
24 | $Context = $Listener.GetContext()
25 |
26 | # Authentication Module
27 | $Identity, $NodePSUserName, $NodePSUserPassword = Get-Authentication -Context $Context -BasicAuthentication $BasicAuthentication -WindowsAuthentication $WindowsAuthentication
28 |
29 | $File = $Context.Request.Url.LocalPath
30 | $Response = $Context.Response
31 | $Response.Headers.Add("Accept-Encoding","gzip");
32 | $Response.Headers.Add("Server","NodePS Server");
33 | $Response.Headers.Add("X-Powered-By","Microsoft PowerShell");
34 | $Response.Headers.Add("Access-Control-Allow-Origin","*");
35 |
36 | # Set Request Parameters
37 | $Request = $Context.Request
38 | $InputStream = $Request.InputStream
39 | $ContentEncoding = $Request.ContentEncoding
40 | $ContentType = $Request.ContentType
41 |
42 | # IP Restriction Module
43 | $IPSessionDrop = Test-IPRestriction -Request $Request -IPRestriction $IPRestriction -IPWhiteList $IPWhiteList
44 |
45 | # Get Query String
46 | $NodePSQuery = Get-NodePSQueryString -Request $Request
47 |
48 | # Get Post Stream
49 | $NodePSPost = Get-NodePSPostStream -InputStream $InputStream -ContentEncoding $ContentEncoding -ContentType $ContentType
50 |
51 | # Get Default Document
52 | if ($File -notlike "*.*" -and $File -like "*/") {
53 | $FolderPath = [System.IO.Directory]::GetCurrentDirectory() + $File
54 | $RequstURL = [string]$Request.Url
55 | $SubfolderName = $File
56 | $File = $File + $DefaultDocument
57 | }
58 | elseif ($File -notlike "*.*" -and $File -notlike "*/") {
59 | $FolderPath = [System.IO.Directory]::GetCurrentDirectory() + $File + "/"
60 | $RequstURL = [string]$Request.Url + "/"
61 | $SubfolderName = $File + "/"
62 | $File = $File + "/" + $DefaultDocument
63 | }
64 | else {
65 | $FolderPath = $Null;
66 | }
67 |
68 | $File = [System.IO.Directory]::GetCurrentDirectory() + $File
69 | $MimeType = Get-MimeType -Extension ((Get-ChildItem $File -EA SilentlyContinue).Extension)
70 |
71 | # NodePS API Support
72 | if ($File -like "*.psxml") {
73 | $File = $File.Replace(".psxml",".ps1")
74 | } elseif ($File -like "*.psjson") {
75 | $File = $File.Replace(".psjson",".ps1")
76 | }
77 | # We do this replace to match the files in the cache if needed
78 | $File = $File -replace "/","\"
79 |
80 | # Content Filtering Module
81 | $ContentSessionDrop = Test-ContentFiltering -ContentFiltering $ContentFiltering -ContentFilterBlackList $ContentFilterBlackList -MimeType $MimeType
82 |
83 | # Check if the file exists in cache or on disk
84 | if ($NodePSConfig.CachedMode) {
85 | $fileExist = $SharedData.CachedPages.ContainsKey($file) -or ($file -notmatch ".*\.ps1$" -and [System.IO.File]::Exists($File))
86 | } else {
87 | $fileExist = [System.IO.File]::Exists($File)
88 | }
89 |
90 | # Stream Content
91 | if ((-not $ContentSessionDrop) -and (-not $IPSessionDrop) -and $fileExist) {
92 | if ($MimeType -in @("text/ps1","text/psxml","text/psjson")) {
93 | try {
94 | $Response.ContentType = Switch ($MimeType) {
95 | "text/ps1" { "text/html" }
96 | "text/psxml" { "text/xml" }
97 | "text/psjson" { "application/json" }
98 | }
99 | $Response.StatusCode = [System.Net.HttpStatusCode]::OK
100 | $LogResponseStatus = $Response.StatusCode
101 | $Utf8NoBomEncoding = New-Object System.Text.UTF8Encoding($False)
102 | $Response = New-Object IO.StreamWriter($Response.OutputStream,$Utf8NoBomEncoding)
103 | if ($NodePSConfig.CachedMode) {
104 | $ScriptBlock = $SharedData.CachedPages[$file]
105 | } else {
106 | $param ="Param(`$NodePSUserName, `$NodePSUserPassword, `$NodePSQuery, `$NodePSPost, `$SharedData, `$Identity)`n"
107 | $ScriptBlock = [scriptblock]::Create($param + ([System.IO.File]::ReadAllText($file)))
108 | }
109 | $ResponseThread = [powershell]::Create()
110 | $null = $ResponseThread.AddScript($ScriptBlock)
111 | $null = $ResponseThread.AddArgument($NodePSUserName)
112 | $null = $ResponseThread.AddArgument($NodePSUserPassword)
113 | $null = $ResponseThread.AddArgument($NodePSQuery)
114 | $null = $ResponseThread.AddArgument($NodePSPost)
115 | $null = $ResponseThread.AddArgument($SharedData)
116 | $null = $ResponseThread.AddArgument($Identity)
117 | $ResponseThread.RunspacePool = $SharedData.RunspacePool
118 | $ResponseHandle = $ResponseThread.BeginInvoke()
119 | Do {
120 | Start-Sleep -Milliseconds 50
121 | }
122 | While ($ResponseHandle.IsCompleted -contains $false)
123 | $ResponseData = $ResponseThread.EndInvoke($ResponseHandle)
124 | $ResponseThread.Dispose()
125 | foreach ($o in $ResponseData) {
126 | $Response.WriteLine($o)
127 | }
128 | } Catch {
129 | Write-Debug "Exception in $($_.InvocationInfo.ScriptName):$($_.InvocationInfo.ScriptLineNumber):$($_.InvocationInfo.Line)"
130 | write-debug $_.Exception.tostring()
131 | }
132 | } else { #for all other files, read static content
133 | try {
134 | $Response.ContentType = "$MimeType"
135 | $FileContent = [System.IO.File]::ReadAllBytes($File)
136 | $Response.ContentLength64 = $FileContent.Length
137 | $Response.StatusCode = [System.Net.HttpStatusCode]::OK
138 | $LogResponseStatus = $Response.StatusCode
139 | $Response.OutputStream.Write($FileContent, 0, $FileContent.Length)
140 | } Catch {
141 | Write-Debug "Exception in $($_.InvocationInfo.ScriptName):$($_.InvocationInfo.ScriptLineNumber):$($_.InvocationInfo.Line)"
142 | write-debug $_.Exception.tostring()
143 | }
144 | }
145 | } else { #requesting a folder, not a file
146 | # Content Filtering and IP Restriction Control
147 | if ((-not $ContentSessionDrop) -and (-not $IPSessionDrop) -and $FolderPath) {
148 | $TestFolderPath = Test-Path -Path $FolderPath
149 | } else {
150 | $TestFolderPath = $false
151 | }
152 |
153 | if ($DirectoryBrowsing -and $TestFolderPath) {
154 | try {
155 | $Response.ContentType = "text/html"
156 | $Response.StatusCode = [System.Net.HttpStatusCode]::OK
157 | $LogResponseStatus = $Response.StatusCode
158 | $Utf8NoBomEncoding = New-Object System.Text.UTF8Encoding($False)
159 | $Response = New-Object IO.StreamWriter($Response.OutputStream,$Utf8NoBomEncoding)
160 | if ($Hostname -eq "+") { $HeaderName = "localhost" } else { $HeaderName = $Hostname[0] }
161 | $DirectoryContent = (Get-DirectoryContent -Path "$FolderPath" -HeaderName $HeaderName -RequestURL $RequestURL -SubfolderName $SubfolderName)
162 | $Response.WriteLine("$DirectoryContent")
163 | } Catch {
164 | Write-Debug "Exception in $($_.InvocationInfo.ScriptName):$($_.InvocationInfo.ScriptLineNumber):$($_.InvocationInfo.Line)"
165 | write-debug $_.Exception.tostring()
166 | }
167 | } else { #folder requested, no folder browsing allowed or folder not exist, you get a 404 (maybe a 501 would be better?)
168 | try {
169 | $Response.ContentType = "text/html"
170 | $Response.StatusCode = [System.Net.HttpStatusCode]::NotFound
171 | $LogResponseStatus = $Response.StatusCode
172 | $Utf8NoBomEncoding = New-Object System.Text.UTF8Encoding($False)
173 | $Response = New-Object IO.StreamWriter($Response.OutputStream,$Utf8NoBomEncoding)
174 | $Response.WriteLine($(Get-404PageContent -Hostname $Hostname))
175 | } Catch {
176 | Write-Debug "Exception in $($_.InvocationInfo.ScriptName):$($_.InvocationInfo.ScriptLineNumber):$($_.InvocationInfo.Line)"
177 | write-debug $_.Exception.tostring()
178 | }
179 | }
180 | }
181 |
182 | # Logging Module
183 | Write-NodePSLog
184 |
185 | # Close Connection
186 | try {
187 | $Response.Close()
188 | } Catch {
189 | $_.Exception.ToString() | ForEach-Object { Add-Content -Value $_ -Path "$LogDirectory\debug.txt" }
190 | Add-Content -Value $_.InvocationInfo.ScriptLineNumber -Path "$LogDirectory\debug.txt"
191 | }
192 | }
193 | }
194 | }
--------------------------------------------------------------------------------
/NodePS/Private/Get-NodePSWelcomeBanner.ps1:
--------------------------------------------------------------------------------
1 | function Get-NodePSWelcomeBanner {
2 |
3 | <#
4 | .SYNOPSIS
5 |
6 | Function to get welcome banner
7 |
8 | .EXAMPLE
9 |
10 | Get-NodePSWelcomeBanner -Hostname "localhost" -Port "8080" -SSL -SSLIP "10.10.10.2" -SSLPort "8443"
11 |
12 | #>
13 |
14 | [CmdletBinding()]
15 | param (
16 |
17 | [Parameter(
18 | Mandatory = $false,
19 | HelpMessage = 'IP Address or Hostname')]
20 | [Alias('IP')]
21 | [string[]]$Hostname,
22 |
23 | [Parameter(
24 | Mandatory = $false,
25 | HelpMessage = 'Port Number')]
26 | [int]$Port,
27 |
28 | [Parameter(
29 | Mandatory = $false,
30 | HelpMessage = 'Enable SSL')]
31 | [switch]$SSL,
32 |
33 | [Parameter(
34 | Mandatory = $false,
35 | HelpMessage = 'SSL IP Address')]
36 | [string[]]$SSLIP,
37 |
38 | [Parameter(
39 | Mandatory = $false,
40 | HelpMessage = 'SSL Port Number')]
41 | [int]$SSLPort
42 | )
43 | # Get Port
44 | if ($Port -ne 80) {
45 | [string]$Port = ":$Port"
46 | } else {
47 | $Port = $null
48 | }
49 |
50 | # Get SSL Port
51 | if ($SSLPort -ne "443") {
52 | [string]$SSLPort = ":$SSLPort"
53 | } else {
54 | [string]$SSLPort = $null
55 | }
56 |
57 | Write-Host " "
58 | Write-Host " Welcome to NodePS Server"
59 | Write-Host " "
60 | Write-Host " "
61 | Write-Host " You can start browsing your webpage from:"
62 | foreach ($h in $Hostname) {
63 | if ($h -eq "+") { $h = "localhost" }
64 | Write-Host " http://$h$Port"
65 | }
66 |
67 | if ($SSL) {
68 | foreach ($ip in $SSLIP) {
69 | Write-Host " https://$ip$SSLPort"
70 | }
71 | }
72 |
73 | Write-Host " "
74 | Write-Host " "
75 | Write-Host " Thanks for using NodePS Server.."
76 | Write-Host " "
77 | Write-Host " "
78 | Write-Host " "
79 | }
80 |
--------------------------------------------------------------------------------
/NodePS/Private/Invoke-AsyncHTTPRequest.ps1:
--------------------------------------------------------------------------------
1 | function Invoke-AsyncHTTPRequest {
2 |
3 | <#
4 | .SYNOPSIS
5 |
6 | Function to invoke async HTTP request
7 |
8 | .EXAMPLE
9 |
10 | Invoke-AsyncHTTPRequest
11 |
12 | #>
13 |
14 | [CmdletBinding(SupportsShouldProcess = $true)]
15 | param (
16 |
17 | [Parameter(
18 | Mandatory = $false,
19 | HelpMessage = 'Script Block')]
20 | $ScriptBlock,
21 |
22 | [Parameter(
23 | Mandatory = $false,
24 | HelpMessage = 'Listener')]
25 | $Listener,
26 |
27 | [Parameter(
28 | Mandatory = $false,
29 | HelpMessage = 'Hostname')]
30 | $Hostname,
31 |
32 | [Parameter(
33 | Mandatory = $false,
34 | HelpMessage = 'Home Directory. Example: C:\inetpub\wwwroot')]
35 | [string]$HomeDirectory,
36 |
37 | [Parameter(
38 | Mandatory = $false,
39 | HelpMessage = 'Log Directory. Example: C:\inetpub\wwwroot')]
40 | [string]$LogDirectory,
41 |
42 | [Parameter(
43 | Mandatory = $false,
44 | HelpMessage = 'NodePSServer Module Path')]
45 | [string]$NodePSModulePath,
46 |
47 | [Parameter(
48 | Mandatory = $false,
49 | HelpMessage = 'Thread Config Path')]
50 | [string]$ThreadConfig,
51 |
52 | [Parameter(
53 | Mandatory = $false,
54 | HelpMessage = 'Shared data container')]
55 | [object]$SharedData,
56 |
57 | [Parameter(
58 | Mandatory = $false,
59 | HelpMessage = 'Thread pool')]
60 | [object]$RunspacePool
61 | )
62 |
63 | $Pipeline = [System.Management.Automation.PowerShell]::Create()
64 | $null = $Pipeline.AddScript($ScriptBlock)
65 | $null = $Pipeline.AddArgument($Listener)
66 | $null = $Pipeline.AddArgument($Hostname)
67 | $null = $Pipeline.AddArgument($HomeDirectory)
68 | $null = $Pipeline.AddArgument($LogDirectory)
69 | $null = $Pipeline.AddArgument($NodePSModulePath)
70 | $null = $Pipeline.AddArgument($ThreadConfig)
71 | $null = $Pipeline.AddArgument($SharedData)
72 | $Pipeline.RunspacePool = $RunspacePool
73 | [psobject]@{
74 | "Handle" = $Pipeline.BeginInvoke()
75 | "Instance" = $Pipeline
76 | }
77 | }
78 |
--------------------------------------------------------------------------------
/NodePS/Private/Invoke-BackgroundJob.ps1:
--------------------------------------------------------------------------------
1 | function Invoke-BackgroundJob {
2 |
3 | <#
4 | .SYNOPSIS
5 |
6 | Function to invoke async HTTP request
7 |
8 | .EXAMPLE
9 |
10 | Invoke-AsyncHTTPRequest
11 |
12 | #>
13 |
14 | [CmdletBinding(SupportsShouldProcess = $true)]
15 | param (
16 |
17 | [Parameter(
18 | Mandatory = $false,
19 | HelpMessage = 'Script Block')]
20 | $ScriptBlock,
21 |
22 | [Parameter(
23 | Mandatory = $false,
24 | HelpMessage = 'Hostname')]
25 | $Hostname,
26 |
27 | [Parameter(
28 | Mandatory = $false,
29 | HelpMessage = 'Port')]
30 | $Port,
31 |
32 | [Parameter(
33 | Mandatory = $false,
34 | HelpMessage = 'Home Directory. Example: C:\inetpub\wwwroot')]
35 | [string]$HomeDirectory,
36 |
37 | [Parameter(
38 | Mandatory = $false,
39 | HelpMessage = 'Log Directory. Example: C:\inetpub\wwwroot')]
40 | [string]$LogDirectory,
41 |
42 | [Parameter(
43 | Mandatory = $false,
44 | HelpMessage = 'Custom Job file Path')]
45 | [string]$CustomJob,
46 |
47 | [Parameter(
48 | Mandatory = $false,
49 | HelpMessage = 'Custom Job Schedule')]
50 | [int]$CustomJobSchedule,
51 |
52 | [Parameter(
53 | Mandatory = $false,
54 | HelpMessage = 'Shared data container')]
55 | [object]$SharedData,
56 |
57 | [Parameter(
58 | Mandatory = $false,
59 | HelpMessage = 'Runspace Pool')]
60 | $RunspacePool
61 | )
62 |
63 | $Pipeline = [System.Management.Automation.PowerShell]::Create()
64 | $null = $Pipeline.AddScript($ScriptBlock)
65 | $null = $Pipeline.AddArgument($Hostname)
66 | $null = $Pipeline.AddArgument($Port)
67 | $null = $Pipeline.AddArgument($HomeDirectory)
68 | $null = $Pipeline.AddArgument($LogDirectory)
69 | $null = $Pipeline.AddArgument($CustomJob)
70 | $null = $Pipeline.AddArgument($CustomJobSchedule)
71 | $null = $Pipeline.AddArgument($SharedData)
72 | $Pipeline.RunspacePool = $RunspacePool
73 | [psobject]@{
74 | "Handle" = $Pipeline.BeginInvoke()
75 | "Instance" = $Pipeline
76 | }
77 | }
78 |
--------------------------------------------------------------------------------
/NodePS/Private/New-NodePSLogHash.ps1:
--------------------------------------------------------------------------------
1 | function New-NodePSLogHash {
2 |
3 | <#
4 | .SYNOPSIS
5 |
6 | Function to hash NodePSServer log file
7 |
8 | .EXAMPLE
9 |
10 | New-NodePSLogHash -LogSchedule "Hourly" -LogDirectory "C:\inetpub\logs"
11 |
12 | #>
13 |
14 | [CmdletBinding(SupportsShouldProcess = $true)]
15 | param (
16 | [Parameter(
17 | Mandatory = $true,
18 | HelpMessage = 'Log Schedule')]
19 | [string]$LogSchedule,
20 |
21 | [Parameter(
22 | Mandatory = $true,
23 | HelpMessage = 'Log Directory Path')]
24 | [string]$LogDirectory
25 | )
26 |
27 | if ($LogSchedule -eq "Hourly") {
28 | $LogNameFormatLastRound = (Get-Date).AddHours(-1).ToString("yyMMddHH")
29 | } else {
30 | $LogNameFormatLastRound = (Get-Date).AddDays(-1).ToString("yyMMdd")
31 | }
32 |
33 | $LogFileNameLastRound = "u_ex" + $LogNameFormatLastRound + ".log"
34 | $LogFilePathLastRound = $LogDirectory + "\" + $LogFileNamLastRound
35 | $LastLogFilePath = $LogFilePathLastRound
36 |
37 | $SigFileName = "u_ex" + $LogNameFormatLastRound + ".sign"
38 | $SigFilePath = $LogDirectory + "\" + $SigFileName
39 | $DateFileName = "u_ex" + $LogNameFormatLastRound + ".date"
40 | $DateFilePath = $LogDirectory + "\" + $DateFileName
41 |
42 | if ([System.IO.File]::Exists($LastLogFilePath)) {
43 | if (![System.IO.File]::Exists($SigFilePath)) {
44 | $LogHashJobArgs = @($LastLogFilePath,$SigFilePath,$DateFilePath)
45 |
46 | try {
47 | $LogHashJob = Start-Job -ScriptBlock {
48 | param ($LastLogFilePath, $SigFilePath, $DateFilePath)
49 | if (![System.IO.File]::Exists($DateFilePath)) {
50 | $HashAlgorithm = "MD5"
51 | $HashType = [Type] "System.Security.Cryptography.$HashAlgorithm"
52 | $Hasher = $HashType::Create()
53 | $DateString = Get-Date -uformat "%d.%m.%Y"
54 | $TimeString = (w32tm /stripchart /computer:time.ume.tubitak.gov.tr /samples:1)[-1].split("")[0]
55 | $DateString = $DateString + " " + $TimeString
56 | $InputStream = New-Object IO.StreamReader $LastLogFilePath
57 | $HashBytes = $Hasher.ComputeHash($InputStream.BaseStream)
58 | $InputStream.Close()
59 | $Builder = New-Object System.Text.StringBuilder
60 | $HashBytes | Foreach-Object { [void] $Builder.Append($_.ToString("X2")) }
61 | $HashString = $Builder.ToString()
62 | $HashString = $HashString + " " + $DateString
63 | $Stream = [System.IO.StreamWriter]$SigFilePath
64 | $Stream.Write($HashString)
65 | $Stream.Close()
66 | $Stream = [System.IO.StreamWriter]$DateFilePath
67 | $Stream.Write($DateString)
68 | $Stream.Close()
69 | $InputStream = New-Object IO.StreamReader $SigFilePath
70 | $HashBytes = $Hasher.ComputeHash($InputStream.BaseStream)
71 | $InputStream.Close()
72 | $Builder = New-Object System.Text.StringBuilder
73 | $HashBytes | Foreach-Object { [void] $Builder.Append($_.ToString("X2")) }
74 | $HashString = $Builder.ToString()
75 | $Stream = [System.IO.StreamWriter]$SigFilePath
76 | $Stream.Write($HashString)
77 | $Stream.Close()
78 | }
79 | } -ArgumentList $LogHashJobArgs
80 | } Catch {
81 | Write-Debug "Exception in $($_.InvocationInfo.ScriptName):$($_.InvocationInfo.ScriptLineNumber):$($_.InvocationInfo.Line)"
82 | write-debug $_.Exception.tostring()
83 | }
84 | }
85 | }
86 | else {
87 | Write-Debug "Could not find log file. $LogDirectory\debug.txt"
88 | }
89 | }
90 |
91 |
92 |
--------------------------------------------------------------------------------
/NodePS/Private/New-NodePSTimeStamp.ps1:
--------------------------------------------------------------------------------
1 | function New-NodePSTimeStamp {
2 |
3 | <#
4 | .SYNOPSIS
5 |
6 | Function to generate time stamp
7 |
8 | .EXAMPLE
9 |
10 | New-NodePSTimeStamp
11 |
12 | #>
13 |
14 | Get-Date -Format "HHmmssfff"
15 | }
16 |
--------------------------------------------------------------------------------
/NodePS/Private/Register-NodePSCertificate.ps1:
--------------------------------------------------------------------------------
1 | function Register-NodePSCertificate {
2 |
3 | <#
4 | .SYNOPSIS
5 |
6 | Function to register NodePS Certificate
7 |
8 | .EXAMPLE
9 |
10 | Register-NodePSCertificate -SSLIP "10.10.10.2" -SSLPort "8443" -Thumbprint "45F53D35AB630198F19A27931283"
11 |
12 | #>
13 |
14 | [CmdletBinding(SupportsShouldProcess = $true)]
15 | param (
16 |
17 | [Parameter(
18 | Mandatory = $false,
19 | HelpMessage = 'SSL IP Address')]
20 | [string]$SSLIP,
21 |
22 | [Parameter(
23 | Mandatory = $false,
24 | HelpMessage = 'SSL Port Number')]
25 | [string]$SSLPort,
26 |
27 | [Parameter(
28 | Mandatory = $false,
29 | HelpMessage = 'SSL Thumbprint')]
30 | $Thumbprint,
31 |
32 | [Parameter(
33 | Mandatory = $false,
34 | HelpMessage = 'Debug Mode')]
35 | $DebugMode = $false
36 | )
37 |
38 | $SSLIPAddresses = @($SSLIP.Split(","))
39 |
40 | foreach ($SSLIPAddress in $SSLIPAddresses) {
41 | $IPPort = $SSLIPAddress + ":" + $SSLPort
42 |
43 | if ($DebugMode) {
44 | # Remove Previous SSL Bindings
45 | netsh http delete sslcert ipport="$IPPort"
46 |
47 | # Add SSL Certificate
48 | netsh http add sslcert ipport="$IPPort" certhash="$Thumbprint" appid="{00112233-4455-6677-8899-AABBCCDDEEFF}"
49 | }
50 | else {
51 | # Remove Previous SSL Bindings
52 | netsh http delete sslcert ipport="$IPPort" | Out-Null
53 |
54 | # Add SSL Certificate
55 | netsh http add sslcert ipport="$IPPort" certhash="$Thumbprint" appid="{00112233-4455-6677-8899-AABBCCDDEEFF}" | Out-Null
56 | }
57 | }
58 | }
59 |
60 |
--------------------------------------------------------------------------------
/NodePS/Private/Request-NodePSCertificate.ps1:
--------------------------------------------------------------------------------
1 | function Request-NodePSCertificate {
2 |
3 | <#
4 | .SYNOPSIS
5 |
6 | Function to create NodePS Certificate request
7 |
8 | .EXAMPLE
9 |
10 | Request-NodePSCertificate
11 |
12 | #>
13 |
14 | $SSLSubject = "NodePSServer"
15 | $SSLName = New-Object -com "X509Enrollment.CX500DistinguishedName.1"
16 | $SSLName.Encode("CN=$SSLSubject", 0)
17 | $SSLKey = New-Object -com "X509Enrollment.CX509PrivateKey.1"
18 | $SSLKey.ProviderName = "Microsoft RSA SChannel Cryptographic Provider"
19 | $SSLKey.KeySpec = 1
20 | $SSLKey.Length = 2048
21 | $SSLKey.SecurityDescriptor = "D:PAI(A;;0xd01f01ff;;;SY)(A;;0xd01f01ff;;;BA)(A;;0x80120089;;;NS)"
22 | $SSLKey.MachineContext = 1
23 | $SSLKey.ExportPolicy = 1
24 | $SSLKey.Create()
25 | $SSLObjectId = New-Object -com "X509Enrollment.CObjectIds.1"
26 | $SSLServerId = New-Object -com "X509Enrollment.CObjectId.1"
27 | $SSLServerId.InitializeFromValue("1.3.6.1.5.5.7.3.1")
28 | $SSLObjectId.add($SSLServerId)
29 | $SSLExtensions = New-Object -com "X509Enrollment.CX509ExtensionEnhancedKeyUsage.1"
30 | $SSLExtensions.InitializeEncode($SSLObjectId)
31 | $SSLCert = New-Object -com "X509Enrollment.CX509CertificateRequestCertificate.1"
32 | $SSLCert.InitializeFromPrivateKey(2, $SSLKey, "")
33 | $SSLCert.Subject = $SSLName
34 | $SSLCert.Issuer = $SSLCert.Subject
35 | $SSLCert.NotBefore = Get-Date
36 | $SSLCert.NotAfter = $SSLCert.NotBefore.AddDays(1825)
37 | $SSLCert.X509Extensions.Add($SSLExtensions)
38 | $SSLCert.Encode()
39 | $SSLEnrollment = New-Object -com "X509Enrollment.CX509Enrollment.1"
40 | $SSLEnrollment.InitializeFromRequest($SSLCert)
41 | $SSLEnrollment.CertificateFriendlyName = 'NodePSServer SSL Certificate'
42 | $SSLCertdata = $SSLEnrollment.CreateRequest(0)
43 | $SSLEnrollment.InstallResponse(2, $SSLCertdata, 0, "")
44 | }
45 |
--------------------------------------------------------------------------------
/NodePS/Private/Start-NodePSLogParser.ps1:
--------------------------------------------------------------------------------
1 | function Start-NodePSLogParser {
2 |
3 | <#
4 | .SYNOPSIS
5 |
6 | Function to parse NodePSServer log files
7 |
8 | .EXAMPLE
9 |
10 | Start-NodePSLogParser -LogPath "C:\inetpub\logs\hourly.log"
11 |
12 | #>
13 |
14 | [CmdletBinding(SupportsShouldProcess = $true)]
15 | param (
16 |
17 | [Parameter(
18 | Mandatory = $true,
19 | HelpMessage = 'Log Path')]
20 | [string]$LogPath
21 | )
22 |
23 | $File = $LogPath
24 | $Log = Get-Content $File | where {$_ -notLike "#[D,S-V]*" }
25 | $Columns = (($Log[0].TrimEnd()) -replace "#Fields: ", "" -replace "-","" -replace "\(","" -replace "\)","").Split(" ")
26 | $Count = $Columns.Length
27 | $Rows = $Log | where {$_ -notLike "#Fields"}
28 | $IISLog = New-Object System.Data.DataTable "IISLog"
29 | foreach ($Column in $Columns) {
30 | $NewColumn = New-Object System.Data.DataColumn $Column, ([string])
31 | $IISLog.Columns.Add($NewColumn)
32 | }
33 | foreach ($Row in $Rows) {
34 | $Row = $Row.Split(" ")
35 | $AddRow = $IISLog.newrow()
36 | for ($i=0;$i -lt $Count; $i++) {
37 | $ColumnName = $Columns[$i]
38 | $AddRow.$ColumnName = $Row[$i]
39 | }
40 | $IISLog.Rows.Add($AddRow)
41 | }
42 | $IISLog
43 | }
44 |
45 |
--------------------------------------------------------------------------------
/NodePS/Private/Test-ContentFiltering.ps1:
--------------------------------------------------------------------------------
1 | # NodePS Server Content Filtering Module
2 | function Test-ContentFiltering {
3 | [CmdletBinding()]
4 | param (
5 | [Parameter(
6 | Mandatory = $true)]
7 | $ContentFiltering,
8 |
9 | [Parameter(
10 | Mandatory = $true)]
11 | $ContentFilterBlackList,
12 |
13 | [Parameter(
14 | Mandatory = $true)]
15 | $MimeType
16 | )
17 | if ($ContentFiltering -eq "On") {
18 | if ($ContentFilterBlackList -match $MimeType) {
19 | Write-Debug "$MimeType is not allowed, dropping.."
20 | $true
21 | }
22 | else {
23 | $false
24 | }
25 | }
26 | else {
27 | $false
28 | }
29 | }
30 |
31 |
--------------------------------------------------------------------------------
/NodePS/Private/Test-IPRestriction.ps1:
--------------------------------------------------------------------------------
1 | # NodePS Server IP Restriction Module
2 | function Test-IPRestriction {
3 | [CmdletBinding()]
4 | param (
5 | [Parameter(
6 | Mandatory = $true)]
7 | $Request,
8 |
9 | [Parameter(
10 | Mandatory = $true)]
11 | $IPRestriction,
12 |
13 | [Parameter(
14 | Mandatory = $true)]
15 | $IPWhiteList
16 | )
17 | $ClientIPAddr = $Request.RemoteEndPoint.Address
18 |
19 | if ($IPRestriction -eq "On" -and !($IPWhiteList -match $ClientIPAddr)) {
20 | Write-Warning "$ClientIPAddr has no permission, dropping.."
21 | return $true
22 | }
23 | return $false
24 |
25 | }
26 |
27 |
--------------------------------------------------------------------------------
/NodePS/Private/Test-IPSettings.ps1:
--------------------------------------------------------------------------------
1 | # NodePS Server IP Address Verification
2 | function Test-IPSettings {
3 | [CmdletBinding()]
4 | param (
5 | [Parameter(
6 | Mandatory = $false)]
7 | $Hostname,
8 |
9 | [Parameter(
10 | Mandatory = $false)]
11 | $SSLIP
12 | )
13 | if ($Hostname -or $SSLIP) {
14 | $IPAddresses = @($Hostname -split "," ; $SSLIP -split "," )
15 | foreach ($IPAddress in $IPAddresses) {
16 | if ($IPAddress -ne "127.0.0.1" -and $IPAddress -ne "::1") {
17 | if ($IPAddress -as [ipaddress]) {
18 | if ($IPAddress -notin (Get-WmiObject Win32_NetworkAdapterConfiguration).IPaddress) {
19 | Write-Warning "$IPAddress does not exist on your current network configuration."
20 | Write-Warning "Aborting.."
21 | return $false
22 | }
23 | }
24 | }
25 | }
26 | }
27 |
28 | return $true
29 | }
30 |
31 |
--------------------------------------------------------------------------------
/NodePS/Private/Write-NodePSLog.ps1:
--------------------------------------------------------------------------------
1 | # NodePS Server Logging Module
2 | # Fields: date time s-sitename s-computername s-ip cs-method cs-uri-stem s-port c-ip cs-version cs(User-Agent) cs(Cookie) cs(Referer) cs-host sc-status
3 | function Write-NodePSLog {
4 | [CmdletBinding()]param()
5 | $LogDate = Get-Date -format yyyy-MM-dd
6 | $LogTime = Get-Date -format HH:mm:ss
7 | $LogSiteName = $Hostname
8 | if ($LogSiteName -eq "+") { $LogSiteName = "localhost" }
9 | $LogComputerName = Get-Content env:computername
10 | $LogServerIP = $Request.LocalEndPoint.Address
11 | $LogMethod = $Request.HttpMethod
12 | $LogUrlStem = $Request.RawUrl
13 | $LogServerPort = $Request.LocalEndPoint.Port
14 | $LogClientIP = $Request.RemoteEndPoint.Address
15 | $LogClientVersion = $Request.ProtocolVersion
16 | if (!$LogClientVersion) { $LogClientVersion = "-" } else { $LogClientVersion = "HTTP/" + $LogClientVersion }
17 | $LogClientAgent = [string]$Request.UserAgent
18 | if (!$LogClientAgent) { $LogClientAgent = "-" } else { $LogClientAgent = $LogClientAgent.Replace(" ","+") }
19 | $LogClientCookie = [string]$Response.Cookies.Value
20 | if (!$LogClientCookie) { $LogClientCookie = "-" } else { $LogClientCookie = $LogClientCookie.Replace(" ","+") }
21 | $LogClientReferrer = [string]$Request.UrlReferrer
22 | if (!$LogClientReferrer) { $LogClientReferrer = "-" } else { $LogClientReferrer = $LogClientReferrer.Replace(" ","+") }
23 | $LogHostInfo = [string]$LogServerIP + ":" + [string]$LogServerPort
24 |
25 | # Log Output
26 | $LogOutput = "$LogDate $LogTime $LogSiteName $LogComputerName $LogServerIP $LogMethod $LogUrlStem $LogServerPort $LogClientIP $LogClientVersion $LogClientAgent $LogClientCookie $LogClientReferrer $LogHostInfo $LogResponseStatus"
27 |
28 | # Logging to Log File
29 | $LogNameFormat = if ($LogSchedule -eq "Hourly") {
30 | Get-Date -format yyMMddHH
31 | } else {
32 | Get-Date -format yyMMdd
33 | }
34 | $LogFileName = "u_ex" + $LogNameFormat + ".log"
35 | $LogFilePath = $LogDirectory + "\" + $LogFileName
36 |
37 | if ($LastCheckDate -ne $LogNameFormat) {
38 | if (![System.IO.File]::Exists($LogFilePath)) {
39 | $LogHeader = "#Fields: date time s-sitename s-computername s-ip cs-method cs-uri-stem s-port c-ip cs-version cs(User-Agent) cs(Cookie) cs(Referer) cs-host sc-status"
40 | Add-Content -Path $LogFilePath -Value $LogHeader -EA SilentlyContinue
41 | }
42 |
43 | # Set Last Check Date
44 | $LastCheckDate = $LogNameFormat
45 | }
46 |
47 | try {
48 | Add-Content -Path $LogFilePath -Value $LogOutput -EA SilentlyContinue
49 | } Catch {
50 | Write-Debug "Exception in $($_.InvocationInfo.ScriptName):$($_.InvocationInfo.ScriptLineNumber):$($_.InvocationInfo.Line)"
51 | write-debug $_.Exception.tostring()
52 | }
53 | }
54 |
55 |
56 |
--------------------------------------------------------------------------------
/NodePS/Public/Start-NodePSServer.ps1:
--------------------------------------------------------------------------------
1 | #Requires -RunAsAdministrator
2 | function Start-NodePSServer {
3 | <#
4 | .SYNOPSIS
5 |
6 | Powershell Web Server to serve HTML and Powershell web contents.
7 |
8 | .DESCRIPTION
9 |
10 | Listens a port to serve web content. Supports HTML and Powershell.
11 |
12 | .EXAMPLE
13 |
14 | Start-NodePSServer -IP 127.0.0.1 -Port 8080
15 |
16 | .EXAMPLE
17 |
18 | Start-NodePSServer -Hostname "NodePSserver.net" -Port 8080
19 |
20 | .EXAMPLE
21 |
22 | Start-NodePSServer -Hostname "NodePSserver.net" -Port 8080 -asJob
23 |
24 | .EXAMPLE
25 |
26 | Start-NodePSServer -Hostname "NodePSserver.net" -Port 8080 -SSL -SSLIP "127.0.0.1" -SSLPort 8443 -asJob
27 |
28 | .EXAMPLE
29 |
30 | Start-NodePSServer -Hostname "NodePSserver.net" -Port 8080 -Debug
31 |
32 | .EXAMPLE
33 |
34 | Start-NodePSServer -Hostname "NodePSserver.net,www.NodePSserver.net" -Port 8080
35 |
36 | .EXAMPLE
37 |
38 | Start-NodePSServer -Hostname "NodePSserver.net,www.NodePSserver.net" -Port 8080 -HomeDirectory "C:\inetpub\wwwroot"
39 |
40 | .EXAMPLE
41 |
42 | Start-NodePSServer -Hostname "NodePSserver.net,www.NodePSserver.net" -Port 8080 -HomeDirectory "C:\inetpub\wwwroot" -LogDirectory "C:\inetpub\wwwroot"
43 |
44 | .EXAMPLE
45 |
46 | Start-NodePSServer -Hostname "NodePSserver.net" -Port 8080 -CustomConfigDirectory "C:\inetpub\config"
47 |
48 | #>
49 |
50 | [CmdletBinding()]
51 | param (
52 |
53 | # Hostname
54 | [Parameter(
55 | Mandatory = $false,
56 | HelpMessage = 'IP Address or Hostname')]
57 | [Alias('IP')]
58 | [string]$Hostname = "localhost",
59 |
60 | # Port Number
61 | [Parameter(
62 | Mandatory = $false,
63 | HelpMessage = 'Port Number')]
64 | [int]$Port = 8080,
65 |
66 | # SSL IP Address
67 | [Parameter(
68 | Mandatory = $false,
69 | HelpMessage = 'SSL IP Address')]
70 | [string]$SSLIP = 127.0.0.1,
71 |
72 | # SSL Port Number
73 | [Parameter(
74 | Mandatory = $false,
75 | HelpMessage = 'SSL Port Number')]
76 | [int]$SSLPort = 8443,
77 |
78 | # SSL certificate Name
79 | [Parameter(
80 | Mandatory = $false,
81 | HelpMessage = 'SSL Friendly Name. Example: NodePSserver.net')]
82 | [string]$SSLName = "NodePSServer SSL Certificate",
83 |
84 | # Home Directory
85 | [Parameter(
86 | Mandatory = $false,
87 | HelpMessage = 'Home Directory. Example: C:\inetpub\wwwroot')]
88 | [string]$HomeDirectory = (Join-Path (Split-Path $PSScriptRoot) "Default\http"),
89 |
90 | # Log Directory
91 | [Parameter(
92 | Mandatory = $false,
93 | HelpMessage = 'Log Directory. Example: C:\inetpub\logs')]
94 | [string]$LogDirectory = (Join-Path (Split-Path $PSScriptRoot) "Default\logs"),
95 |
96 | # Custom Config Directory
97 | [Parameter(
98 | Mandatory = $false,
99 | HelpMessage = 'Custom Config Directory. Example: C:\inetpub\config')]
100 | [string]$CustomConfigDirectory = (Join-path (Split-Path $PSScriptRoot) "Default\Config"),
101 |
102 | # Custom Job Schedule
103 | [Parameter(
104 | Mandatory = $false,
105 | HelpMessage = 'Custom Job Schedule. Example: 1, 5, 10, 20, 30, 60')]
106 | [ValidateSet("1","5","10","20","30","60")]
107 | [string]$CustomJobSchedule = "5",
108 |
109 | # Background Job Credentials
110 | [Parameter(
111 | Mandatory = $false,
112 | HelpMessage = 'Run Background Job as a different User')]
113 | [System.Management.Automation.PSCredential]$JobCredentials,
114 |
115 | # Enable SSL
116 | [Parameter(
117 | Mandatory = $false,
118 | HelpMessage = 'Enable SSL')]
119 | [switch]$SSL,
120 |
121 | # Background Job
122 | [Parameter(
123 | Mandatory = $false,
124 | HelpMessage = 'Run As Background Job')]
125 | [switch]$asJob
126 | )
127 | # Strict mode for clean code
128 | Set-StrictMode -Version latest
129 |
130 | $ServerConfig = Join-Path $CustomConfigDirectory "ServerConfig.ps1"
131 | $ThreadConfig = Join-Path $CustomConfigDirectory "ThreadConfig.ps1"
132 | $CustomJob = Join-Path $CustomConfigDirectory "CustomJob.ps1"
133 |
134 | # Get NodePS Server Module Path
135 | $NodePSModulePath = Split-Path $PSScriptRoot
136 |
137 | # Break Script If Something's Wrong
138 | if (!(Test-IPSettings -Hostname $Hostname -SSLIP $SSLIP)) {
139 | return
140 | } else {
141 | if ($Hostname) {
142 | $Hostname = @($Hostname -split ",")
143 | }
144 | if ($SSLIP) {
145 | $SSLIP = @($SSLIP -split ",")
146 | }
147 |
148 | }
149 |
150 | # Enable Background Job
151 | if ($asJob) {
152 | if (!$JobCredentials) {
153 | Write-Warning "Please specify user credentials for NodePS Server background job."
154 | $JobCredentials = Get-Credential
155 | $JobPassword = $JobCredentials.GetNetworkCredential().Password
156 | }
157 | $JobUsername = $JobCredentials.UserName
158 | $JobPassword = $JobCredentials.GetNetworkCredential().Password
159 |
160 | $CheckTask = Get-ScheduledTask -TaskName "NodePSServer-$($Hostname[0])-$Port" -ErrorAction SilentlyContinue
161 |
162 | if ($CheckTask) {
163 | Write-Warning "This job already exists. You should run it from Scheduled Jobs."
164 | Write-Warning "Aborting..."
165 | return
166 | } else {
167 | try {
168 | # Prepare Job Information
169 | $taskName = "NodePSServer-$($Hostname[0])-$Port"
170 | $taskScriptBlock = "Import-Module $NodePSModulePath; "
171 | $taskScriptBlock += "$($MyInvocation.MyCommand) "
172 |
173 | foreach ($k in ($PSBoundParameters.keys.GetEnumerator() | Where-Object { $_ -notin @('asjob','jobcredentials') })) {
174 | if ($PSBoundParameters[$k] -is [array]) {
175 | $taskScriptBlock += "-$($k) @('$($PSBoundParameters[$k] -join "','")') "
176 | } elseif($PSBoundParameters[$k] -is [switch] -and $PSBoundParameters[$k] -eq $true) {
177 | $taskScriptBlock += "-$($k) "
178 | } else {
179 | $taskScriptBlock += "-$($k) $($PSBoundParameters[$k]) "
180 | }
181 | }
182 | $action = New-ScheduledTaskAction -Execute 'Powershell.exe' -Argument "-noProfile -ExecutionPolicy Bypass -command `"&{$taskScriptBlock}`""
183 | $trigger = New-ScheduledTaskTrigger -AtStartup
184 | $settings = New-ScheduledTaskSettingsSet -Compatibility Win7 -Hidden -AllowStartIfOnBatteries
185 | $settings.ExecutionTimeLimit = "PT0S"
186 |
187 | Register-ScheduledTask -Action $action -Trigger $trigger -TaskName $taskName -User $JobUsername -Password $JobPassword -Settings $settings -RunLevel Highest | Out-Null
188 | Start-ScheduledTask -TaskName $taskName | Out-Null
189 |
190 | # NodePS Server Welcome Banner
191 |
192 | Get-NodePSWelcomeBanner -Hostname $Hostname -Port $Port -SSL:$SSL -SSLIP $SSLIP -SSLPort $SSLPort
193 | } catch {
194 | Write-Debug "An error occured while trying to create the task."
195 | Write-Debug $_
196 | }
197 | }
198 | } else {
199 |
200 | # prepare a container with data shared across threads
201 | $SharedData = [hashtable]::Synchronized(@{})
202 |
203 | # Prepare a container with configuration value
204 | $NodePSConfig = @{}
205 |
206 | # NodePS Server Custom Config
207 | Write-Verbose "Reading server configuration file..."
208 | . $ServerConfig
209 |
210 | if ($PSBoundParameters['Debug']) {
211 | Write-Debug "Setting only 1 listening thread for debug."
212 | $NodePSConfig.Threads = 1
213 | }
214 |
215 | # Total processes is 2 * listening threads (to account for script threads) + 1 for the background thread
216 | try {
217 | $SessionState = [system.management.automation.runspaces.initialsessionstate]::CreateDefault()
218 | $MaxThread = 2 * $NodePSConfig.Threads + 1
219 | $RunspacePool = [runspacefactory]::CreateRunspacePool(1, $MaxThread, $SessionState, $Host)
220 | $RunspacePool.Open()
221 | $SharedData.RunspacePool = $RunspacePool
222 | } catch {
223 | Write-Debug "Exception in $($_.InvocationInfo.ScriptName):$($_.InvocationInfo.ScriptLineNumber):$($_.InvocationInfo.Line)"
224 | write-debug $_.Exception.tostring()
225 | }
226 |
227 | # If cached mode is active, we prepare the caching hashtable
228 | if ($NodePSConfig.CachedMode) {
229 | Write-Verbose "Cache Mode On, preparing the cache..."
230 | $SharedData.CachedPages = @{}
231 | $param ="Param(`$NodePSUserName, `$NodePSUserPassword, `$NodePSQuery, `$NodePSPost, `$SharedData)`n"
232 |
233 | foreach ($p in (Get-ChildItem $HomeDirectory -Filter "*ps1").fullname) {
234 | Write-Verbose "Caching $p"
235 | $SharedData.CachedPages[$p] = [scriptblock]::Create($param + [io.file]::ReadAllText($p))
236 | }
237 | }
238 |
239 | Write-Verbose "Starting background jobs..."
240 | # NodePS Server Scheduled Background Jobs
241 | $NodePSJobArgs = @($NodePSModulePath,$LogDirectory)
242 | $NodePSJob = Start-Job -scriptblock {
243 | param ($NodePSModulePath,$LogDirectory)
244 | Get-ChildItem $NodePSModulePath\Private\*.ps1 -Recurse | ForEach-Object {. $_.FullName }
245 |
246 | while ($true) {
247 | Start-Sleep -Seconds 3600
248 | New-NodePSLogHash -LogSchedule "Hourly" -LogDirectory $LogDirectory
249 | }
250 | } -ArgumentList $NodePSJobArgs
251 |
252 | # NodePS Server Custom Background Jobs
253 | $NodePSCustomJobScriptBlock = {
254 | param ($Hostname, $Port, $HomeDirectory, $LogDirectory, $CustomJob, $CustomJobSchedule, $SharedData)
255 | while ($true) {
256 | Start-Sleep -Seconds 60
257 |
258 | # Get Job Time
259 | [int]$JobTime = Get-Date -format mm
260 | if ($CustomJob) {
261 | if ($CustomJobSchedule -eq "1") {
262 | # NodePS Server Custom Jobs (at every 1 minute)
263 | . $CustomJob
264 | } elseif ($CustomJobSchedule -in @("5","10","20","30") -and !($JobTime % $CustomJobSchedule) ) {
265 | # NodePS Server Custom Jobs (at every 5 minutes)
266 | . $CustomJob
267 | } elseif ($CustomJobSchedule -eq "60" -and $JobTime -eq 0) {
268 | # NodePS Server Custom Jobs (at every hour)
269 | . $CustomJob
270 | }
271 | }
272 | }
273 | }
274 | $NodePSCustomJobParams = @{
275 | ScriptBlock = $NodePSCustomJobScriptBlock
276 | Hostname = $Hostname
277 | Port = $Port
278 | HomeDirectory = $HomeDirectory
279 | LogDirectory = $LogDirectory
280 | CustomJob = $CustomJob
281 | CustomJobSchedule = $CustomJobSchedule
282 | SharedData = $SharedData
283 | RunspacePool = $RunspacePool
284 | }
285 |
286 | $NodePSCustomJob = Invoke-BackgroundJob @NodePSCustomJobParams
287 |
288 | Write-Verbose "Create the HTTPListener..."
289 | try {
290 | $Listener = New-Object Net.HttpListener
291 | } catch {
292 | Write-Debug "Exception in $($_.InvocationInfo.ScriptName):$($_.InvocationInfo.ScriptLineNumber):$($_.InvocationInfo.Line)"
293 | write-debug $_.Exception.tostring()
294 | }
295 |
296 | Write-Verbose "Add Prefix Urls..."
297 | try {
298 | foreach ($Host in $Hostname) {
299 | $Host = $Host -replace "^localhost$","+"
300 | $Prefix = "http://" + $Host + ":" + $Port + "/"
301 | $Listener.Prefixes.Add($Prefix)
302 | }
303 |
304 | if ($SSL) {
305 | foreach ($SSLIPAddress in $SSLIP) {
306 | $SSLIPAddress = $SSLIPAddress -replace "^localhost$","+"
307 | $Prefix = "https://" + $SSLIPAddress + ":" + $SSLPort + "/"
308 | $Listener.Prefixes.Add($Prefix)
309 | }
310 | }
311 | } catch {
312 | Write-Debug "Exception in $($_.InvocationInfo.ScriptName):$($_.InvocationInfo.ScriptLineNumber):$($_.InvocationInfo.Line)"
313 | Write-Debug $_.Exception.tostring()
314 | }
315 |
316 | Write-Verbose "Start Listener..."
317 | try {
318 | $Listener.Start()
319 | } catch {
320 | Write-Error "Exception in $($_.InvocationInfo.ScriptName):$($_.InvocationInfo.ScriptLineNumber):$($_.InvocationInfo.Line)"
321 | write-Error $_.Exception.tostring()
322 | return
323 | }
324 |
325 | try {
326 | if ($SSL) {
327 | Write-Verbose "Configure SSL..."
328 | $NodePSCert = Get-ChildItem -Recurse Cert: | Where-Object { $_.FriendlyName -eq $SSLName }
329 |
330 | if (!$NodePSCert) {
331 | Write-Warning "Couldn't find your SSL certificate."
332 | write-Warning "Creating Self-Signed SSL certificate.."
333 |
334 | Request-NodePSCertificate
335 | $NodePSCert = Get-ChildItem -Recurse Cert: | Where-Object { $_.FriendlyName -eq "NodePSServer SSL Certificate" }
336 | }
337 |
338 | # Register SSL Certificate
339 | $CertThumbprint = $NodePSCert[0].Thumbprint
340 | Register-NodePSCertificate -SSLIP $SSLIP -SSLPort $SSLPort -Thumbprint $CertThumbprint
341 | }
342 | } catch {
343 | Write-Debug "Exception in $($_.InvocationInfo.ScriptName):$($_.InvocationInfo.ScriptLineNumber):$($_.InvocationInfo.Line)"
344 | Write-Debug $_.Exception.tostring()
345 | }
346 | # NodePS Server Welcome Banner
347 | try {
348 | Get-NodePSWelcomeBanner -Hostname $Hostname -Port $Port -SSL:$SSL -SSLIP $SSLIP -SSLPort $SSLPort
349 | } Catch {
350 | Write-Debug "Exception in $($_.InvocationInfo.ScriptName):$($_.InvocationInfo.ScriptLineNumber):$($_.InvocationInfo.Line)"
351 | Write-Debug $_.Exception.tostring()
352 | }
353 |
354 | $NodePSAsyncHTTPRequestParams = @{
355 | ScriptBlock = Get-NodePSThreadScriptBlock
356 | Listener = $Listener
357 | Hostname = $Hostname
358 | HomeDirectory = $HomeDirectory
359 | LogDirectory = $LogDirectory
360 | NodePSModulePath = $NodePSModulePath
361 | ThreadConfig = $ThreadConfig
362 | SharedData = $SharedData
363 | RunspacePool = $RunspacePool
364 | }
365 |
366 | # Let's finally start the listening thread(s)
367 | $Threads = 1..$NodePSConfig.Threads | ForEach-Object { Invoke-AsyncHTTPRequest @NodePSAsyncHTTPRequestParams }
368 |
369 | try {
370 | [System.Console]::TreatControlCAsInput = $true
371 | while ($true) {
372 | if ([System.Console]::KeyAvailable) {
373 | $key = [System.Console]::ReadKey($true)
374 | if (($key.modifiers -band [System.ConsoleModifiers]"control") -and ($key.key -eq "C")) {
375 | Write-Verbose "Terminating..."
376 | break
377 | }
378 | Start-Sleep -Seconds 1
379 | }
380 | }
381 | } finally {
382 | [console]::TreatControlCAsInput = $false
383 | try {
384 | $Listener.Stop()
385 | $Listener.Close()
386 | } Catch {
387 | Write-Warning $_.Exception.ToString()
388 | }
389 |
390 | while ([bool]($Threads | Where-Object {[bool]$_.Handle})) {
391 | ForEach ($thread in ($Threads | Where-Object {$_.Handle.IsCompleted -eq $True})) {
392 | $Thread.Instance.EndInvoke($Thread.Handle)
393 | $Thread.Instance.Dispose()
394 | $Thread.Instance = $Null
395 | $Thread.Handle = $Null
396 | }
397 | if ($Threads | Where-Object {[bool]$_.Handle}) {
398 | Write-verbose ("Waiting for {0} threads to finish..." -f ($Threads | Where-Object {[bool]$_.Handle}).count)
399 | }
400 | Start-Sleep -Seconds 1
401 | }
402 | $RunspacePool.Close() | Out-Null
403 | $RunspacePool.Dispose() | Out-Null
404 |
405 | foreach ($session in Get-PSSession) {
406 | Write-Verbose ("Closing session {0}" -f $session.Name)
407 | }
408 |
409 | # We stop and close the internal job
410 | $NodePSJob | Stop-Job -PassThru | Remove-Job |Out-Null
411 | }
412 | }
413 | }
414 |
415 |
416 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | NodePS
2 | =============
3 |
4 | This is a WebServer written in PowerShell, as a module, which is able to read and execute PowerShell code.
5 |
6 | * Thanks to Yusuf Ozturk of [PoSH Server](http://www.poshserver.net/) fame for the original codebase
7 | * Thanks to [RamblingCookieMonster](https://github.com/RamblingCookieMonster) for his blog articles about PowerShell modules and about contributing
8 | * Thanks to my teammates and my bosses, for the feedbacks and support
9 |
10 | Caveats:
11 |
12 | * Requires Powershell v4 minimum
13 | * No testing published. Maybe one day when I get around reading on Pester. Contributions welcome!
14 | * The WebServer use a .Net object that requires local administrator rights. Please be careful and maybe put it behind a reverse proxy (IIS can do it).
15 | * Naming conventions and coding style subject to change. Suggestions welcome!
16 |
17 | #Functionality
18 |
19 | * Webserver allowing to publish script written in PowerShell. Like NodeJS for JavaScript. But multithreaded out-off-the-box.
20 | * Basic Auth, Windows Auth (local or domain)
21 | * Can be used to server static files (for production, it's better to reverse proxy and use IIS for static content)
22 | * Support JSON and XML headers in response
23 | * "Safe" threads running the PowerShell script
24 | * Shared variables between threads available (for session or other)
25 | * IP filtering, content blocking
26 |
27 | #Instructions
28 |
29 | ```powershell
30 | # One time setup
31 | # Download the repository
32 | # Unblock the zip
33 | # Extract the NodePS folder to a module path (e.g. $env:USERPROFILE\Documents\WindowsPowerShell\Modules\)
34 |
35 | # Import the module. You need to be in an elevated shell.
36 | Import-Module NodePS #Alternatively, Import-Module \\Path\To\NodePS
37 |
38 | # Get public command in the module
39 | Get-Command -Module NodePS
40 |
41 | # Get help for a command
42 | Get-Help Start-NodePSServer -Full
43 |
44 | # Start the WebServer with all default settings
45 | Start-NodePSServer
46 |
47 | # Start the WebServer on https with self-generated certificate
48 | Start-NodePSServer -SSL -SSLIP "127.0.0.1" -SSLPort 443
49 |
50 | # Start the WebServer as a Scheduled Task
51 | Start-NodePSServer -asJob
52 |
53 | ```
54 |
--------------------------------------------------------------------------------