From a4146d258639aaedf849b458feba8a44a6ff89e3 Mon Sep 17 00:00:00 2001 From: joeyaiello Date: Tue, 12 Jul 2016 15:51:03 -0700 Subject: [PATCH 1/4] add value to PSGet demo --- demos/1-PowerShellGet.ps1 | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/demos/1-PowerShellGet.ps1 b/demos/1-PowerShellGet.ps1 index 8a3a704953..769fa6f449 100644 --- a/demos/1-PowerShellGet.ps1 +++ b/demos/1-PowerShellGet.ps1 @@ -4,11 +4,13 @@ Get-PackageProvider #(should show 2 providers - NuGet,PowerShellGet) ## Using PowerShellGet find and install other demos +# Value: equivalent of pypi +# Look for all the modules we'll be demoing today +Find-Module -Tag 'Open PowerShell','Demos' +# Pipe this to Install-Module to install them Find-Module -Tag 'Open PowerShell','Demos' | Install-Module -Verbose Get-Module - -# Find and Download node.js from nuget.org -Find-Package -Name node.js -ProviderName NuGet -Verbose -Source http://nuget.org/api/v2 +# Note that ScriptAnalyzer gets installed because the VSCode demo is dependent upon it # Register trusted endpoints Register-PackageSource -Name NuGet -Location http://nuget.org/api/v2 -Trusted -ProviderName NuGet From 0c38f29d68ecb606223232d632ce99c09434c519 Mon Sep 17 00:00:00 2001 From: joeyaiello Date: Tue, 12 Jul 2016 16:00:13 -0700 Subject: [PATCH 2/4] add comment-level demos We've signed off on these demos conceptually. The next step is for them to be implemented and all blocking engineering work needs to be enumerated and solved. --- demos/apache.ps1 | 14 ++++++++++++++ demos/crontab.ps1 | 9 +++++++++ demos/dsc.ps1 | 11 +++++++++++ demos/json.ps1 | 11 +++++++++++ demos/remoting.ps1 | 2 ++ demos/rest.ps1 | 7 +++++++ demos/xml.ps1 | 42 ++++++++++++++++++++++++++++++++++++++++++ 7 files changed, 96 insertions(+) create mode 100644 demos/apache.ps1 create mode 100644 demos/crontab.ps1 create mode 100644 demos/dsc.ps1 create mode 100644 demos/json.ps1 create mode 100644 demos/remoting.ps1 create mode 100644 demos/rest.ps1 create mode 100644 demos/xml.ps1 diff --git a/demos/apache.ps1 b/demos/apache.ps1 new file mode 100644 index 0000000000..e9f3cd2bcf --- /dev/null +++ b/demos/apache.ps1 @@ -0,0 +1,14 @@ +# Get-ApacheVHosts +# Enumerate configured virtual hosts (web sites) on an apache server + +# New-ApacheVHost +# Given defined parameters, create a $ServerName.conf virtual host config file at $VHostsDirectory + +# Get-ApacheModules +# List installed Apache Modules + +# Demo execution: +# Run Get-ApacheVHosts and enumerate configured virtual hosts +# Run Get-ApacheModules to show installed Apache modules +# Run New-ApacheVHost to create a new virtual host and restart Apache +# Run Get-ApacheVhosts to show the newly created virtual host diff --git a/demos/crontab.ps1 b/demos/crontab.ps1 new file mode 100644 index 0000000000..d90e2dbdb8 --- /dev/null +++ b/demos/crontab.ps1 @@ -0,0 +1,9 @@ +# Use the crontab module available at ./modules/CronTab + +# Get the existing cron jobs + +# Sort them by data + +# Create a new one using a DateTime object + +# Show in bash that the new cron job exists diff --git a/demos/dsc.ps1 b/demos/dsc.ps1 new file mode 100644 index 0000000000..c1fdd69037 --- /dev/null +++ b/demos/dsc.ps1 @@ -0,0 +1,11 @@ +# DSC MOF Compilation +# DSC Configuration() script that: +# Defines base configuration users, groups, settings +# Uses PS function to set package configuration (ensure=Present) for an array of packages +# Probes for the existence of a package (Apache or MySQL) and conditionally configures the workload. I.e., if Apache is installed, configure Apache settings + +# Demo execution: +# Show the .ps1 +# Run the .ps1 to generate a MOF +# Apply the MOF locally with Start-DSCConfiguration +# Show the newly configured state \ No newline at end of file diff --git a/demos/json.ps1 b/demos/json.ps1 new file mode 100644 index 0000000000..4804ffc699 --- /dev/null +++ b/demos/json.ps1 @@ -0,0 +1,11 @@ +# Get-Mongostat +# Get mongodb statistics with parsed JSON + +# journalctl is a native tool to emit SystemD's journal, which includes diagnostic info pertaining to SystemD services +# Show-JournalCtl +# Given journalctl parameters, run journalctl with a -o json to emit JSON, e.g. journalctl $Parameters -o json --no-pager +# Return structured data from Journal + +# Demo execution +# Show journatcl example +# Using Where & Sort, filter journal output to drill into a specific problem (e.g. service failed to start) \ No newline at end of file diff --git a/demos/remoting.ps1 b/demos/remoting.ps1 new file mode 100644 index 0000000000..fe909db1b9 --- /dev/null +++ b/demos/remoting.ps1 @@ -0,0 +1,2 @@ +# Show PSRP working over OpenSSH +# Includes Windows -> Linux and Linux -> Windows \ No newline at end of file diff --git a/demos/rest.ps1 b/demos/rest.ps1 new file mode 100644 index 0000000000..a7b8c799fd --- /dev/null +++ b/demos/rest.ps1 @@ -0,0 +1,7 @@ +# Get all repositories from the GitHub API, sort by most pull requests, most stars, most forks, etc. + +# Get repo info (json) from the github api +# Convert json to PS object +# Set the private status to false +# Convert back to json +# Push the new json back to the github api \ No newline at end of file diff --git a/demos/xml.ps1 b/demos/xml.ps1 new file mode 100644 index 0000000000..151ee628fb --- /dev/null +++ b/demos/xml.ps1 @@ -0,0 +1,42 @@ +Dev: XML legacy [ETS?] +What are some xml workloads we can simplify with XML parsing? +Maybe cracking open some repository metadata? +JEE servers use XML pretty extensively for configuration. Perhaps a script to adjust JEE server settings? Obviously, parsing XML in bash is fraught with danger... + +PS /etc/tomcat> $tomcatserverfile="/usr/share/tomcat/conf/server.xml" +PS /etc/tomcat> [xml]$tomcatconfig=Get-Content $tomcatserverfile +PS /etc/tomcat> $tomcatconfig.Server + + +port : 8005 +shutdown : SHUTDOWN +#comment : { Security listener. Documentation at /docs/config/listeners.html + + , APR library loader. Documentation at /docs/apr.html , Initialize Jasper prior to webapps are loaded. Documentation at + /docs/jasper-howto.html , Prevent memory leaks due to use of particular java/javax APIs...} +Listener : {Listener, Listener, Listener, Listener...} +GlobalNamingResources : GlobalNamingResources +Service : Service + + + + +PS /etc/tomcat> $tomcatconfig.Server.port +8005 +PS /etc/tomcat> $tomcatconfig.Server.Listener + +className SSLEngine +--------- --------- +org.apache.catalina.core.AprLifecycleListener on +org.apache.catalina.core.JasperListener +org.apache.catalina.core.JreMemoryLeakPreventionListener +org.apache.catalina.mbeans.GlobalResourcesLifecycleListener +org.apache.catalina.core.ThreadLocalLeakPreventionListener + + +PS /etc/tomcat> $tomcatconfig.Server.Service + +name #comment +---- -------- +Catalina {The connectors can use a shared executor, you can define one or more named thread pools, ... + From 73dc2fd4d48bb2002b70f38e6041f81f1307cd87 Mon Sep 17 00:00:00 2001 From: joeyaiello Date: Tue, 12 Jul 2016 16:54:08 -0700 Subject: [PATCH 3/4] add Samples folder --- .../ApacheHTTPServer/ApacheVirtualHosts.psm1 | 173 ++++++++++++++++ samples/modules/CronTab/CronTab.ps1xml | 69 +++++++ samples/modules/CronTab/CronTab.psd1 | Bin 0 -> 3520 bytes samples/modules/CronTab/CronTab.psm1 | 189 ++++++++++++++++++ samples/modules/README.md | 1 + 5 files changed, 432 insertions(+) create mode 100644 samples/modules/ApacheHTTPServer/ApacheVirtualHosts.psm1 create mode 100644 samples/modules/CronTab/CronTab.ps1xml create mode 100644 samples/modules/CronTab/CronTab.psd1 create mode 100644 samples/modules/CronTab/CronTab.psm1 create mode 100644 samples/modules/README.md diff --git a/samples/modules/ApacheHTTPServer/ApacheVirtualHosts.psm1 b/samples/modules/ApacheHTTPServer/ApacheVirtualHosts.psm1 new file mode 100644 index 0000000000..94710c8130 --- /dev/null +++ b/samples/modules/ApacheHTTPServer/ApacheVirtualHosts.psm1 @@ -0,0 +1,173 @@ +$moduleRoot = Split-Path -Path $MyInvocation.MyCommand.Path + + +Function New-ApacheVHost { + [CmdletBinding()] + param ( + [parameter (Mandatory = $true)][string]$ServerName, + [string]$VHostsDirectory, + [parameter (Mandatory = $true)][string]$DocumentRoot, + [parameter (Mandatory = $true)][string]$VirtualHostIPAddress, + [string[]]$ServerAliases, + [parameter (Mandatory = $true)][string]$VirtualHostPort, + [string]$ServerAdmin, + [string]$CustomLogPath, + [string]$ErrorLogPath + ) + + if ($VHostsDirectory -notlike "*/*"){ + #Try to find default + if (Test-Path "/etc/httpd/conf.d"){ + $VHostsDirectory = "/etc/httpd/conf.d/" + } + if (Test-Path "/etc/apache2/sites-enabled"){ + $VHostsDirectory = "/etc/apache2/sites-enabled" + } + } + + if (!(Test-Path $VHostsDirectory)){ + Write-Error "Specified virtual hosts directory does not exist: $VHostsDirectory" + exit 1 + } + + $vHostDef = ".*:[0-9]*)(?.*)\((?.*)\)" + $VHostProps = $matches + $vhobject |Add-Member -type NoteProperty -name "ServerName" -value $matches.ServerName.Trim() + $vhobject |Add-Member -type NoteProperty -name "ListenAddress" -value $matches.Listen.Trim() + $vhobject |Add-Member -type NoteProperty -name "ConfFile" -value $matches.ConfFile.Trim() + $Vhosts += $vhobject + } + + } + + Return $Vhosts + +} + +Function Restart-ApacheHTTPServer{ + [CmdletBinding()] + Param( + [boolean]$Graceful + ) + + if ($Graceful -eq $null){$Graceful = $fase} + + $cmd = $null + if (Test-Path "/usr/sbin/apache2ctl"){ + $cmd = "/usr/sbin/apache2ctl" + }elseif(Test-Path "/usr/sbin/httpd"){ + $cmd = "/usr/sbin/httpd" + } + + if ($cmd -eq $null){ + Write-Error "Unable to find httpd/apache2ctl command" + exit -1 + } + + if ($Graceful){ + $cmd = $cmd += " -k graceful" + }else{ + $cmd = $cmd += " -k restart" + } + + Invoke-Expression $Cmd +} + +Function Get-ApacheModules{ + $cmd = $null + if (Test-Path "/usr/sbin/apache2ctl"){ + $cmd = "/usr/sbin/apache2ctl" + }elseif(Test-Path "/usr/sbin/httpd"){ + $cmd = "/usr/sbin/httpd" + } + + if ($cmd -eq $null){ + Write-Error "Unable to find httpd/apache2ctl command" + exit -1 + } + + $cmd = $cmd += " -M |grep -v Loaded" + + $ApacheModules = @() + function New-ModuleObj { + New-Object PSObject -Property @{} + } + + + $Results = Invoke-Expression $cmd + Foreach ($mod in $Results){ + $modObj = New-ModuleObj + $modObj | Add-Member -type NoteProperty -name "Module" -value $mod.trim() + $ApacheModules += $modObj + } + + Return $ApacheModules + +} diff --git a/samples/modules/CronTab/CronTab.ps1xml b/samples/modules/CronTab/CronTab.ps1xml new file mode 100644 index 0000000000..1d1f1f90d8 --- /dev/null +++ b/samples/modules/CronTab/CronTab.ps1xml @@ -0,0 +1,69 @@ + + + + + + Default + + CronJob + + + + + + 10 + Left + + + + 10 + Left + + + + 10 + Left + + + + 10 + Left + + + + 10 + Left + + + + Left + + + + + + + Minute + + + Hour + + + DayOfMonth + + + Month + + + DayOfWeek + + + Command + + + + + + + + \ No newline at end of file diff --git a/samples/modules/CronTab/CronTab.psd1 b/samples/modules/CronTab/CronTab.psd1 new file mode 100644 index 0000000000000000000000000000000000000000..23d9d95f051b15feb3b1c0ca41ca273156cd41b4 GIT binary patch literal 3520 zcmbuBTTc{05QXd6#Q!jf4`L!J#_NNLL{KqE2p8XXVHZZ(nRRy&jp47W=j)>F>Dd|7 z7_!WztE*0(sy;P8f4sEscGGTz-z_U_-;Qi%rA=+2r-{{eZ0B}nBR$nxDQu|K$_Bds zwq!BZn%fR+uD@E|O4%;7|5(-+dRo}2?)YEIf*1q&D{U;Bx!&IkSoXBH*3*0aPY7Pf z{{@#cv~wu?srF55O)JezKFHrpD`l`PWPdKJVR%a};}(h(#}PCmw|zN|2a3I> zAJ+%1==+K`)gPS2?03cPrm}$pM>P+KU&(4BTX-sk5C*$!3nT7JTT!fSS(4FL-QUUb z-m(o@ohx(ad?D{V!|`WbNAgeQN+B8PEiuR8O|vG64LE&chvt4g^T*2fnUD_cxjohH z)!^%){H@v}t@zzQ8I5$mD(f|M0#8S}rv}e-_q4^?y3m2a`|P?3fho6kTWDs7T+Y{t^5lfk@qRw= zLNyBEb|n4v07Ki8Gq9rk@5sl)!1)v1Epu{DZ`aiYXSyaVoW+?i&^I%KlVkODex^3U zdQymZwoK#}Nqx^61pwY+=xp$Wr3^j=>~&v!rYKUD-G=Xw=+bcGp+ zbI#0(>~aOkb9^1xXOGvy6%BS)#0Oflrc*ajM0oboMMoEUQ)?He%C+uPca`3k;dE0| z7;yyswQa_qOXF&30h}Gl8=4wBEzcoG*3O92pXz}R$30ReQKP6EaVB9ksdG|-yIP5y zk}ZZHS}PnD`=PiaF*|YN$QGz`o!Ssr-bQ44A(jL zz#2O0ord?BJiFFKwFfI+Smg@3<&N!U$mhcAR(E@iHZvx@H+K}_Lh2VQ^-i&dI#GA^ z+Y4AZ320`Q#T%_GI@X#qj?O6M!xaSnxEm-VuP-yjd&ZyXIaZP0X6!_eD{-`z8pAV%^8a4 zc1CC^yAvO29=hJ_3dM!2W{M0asG-+4=QN?Brp>RVLeKo=*!!%a^)2l<5VDi2zULbO zb!^V+Zf%IXx8uj_ZHKHAnb??K|D6qVwEA}UK?_Vj)99Ir&!&iovP9HK@h9gI8T^?GdR zm@`F>426*S)s508+DEOTu>H)ribuQu!--xpSNtsb+y;mDhJVvtH)r}$Ze98O7kp?L z-GkPQY)2;xuF%l*T@b(Z(=_R;XTLXB)#aLADiZbF6e~;-kD8y$Wlf1X+PAx@tVsp> l{ea+YU}CCo + [CmdletBinding(SupportsShouldProcess=$true,ConfirmImpact="High")] + param ( + [Alias("u")][Parameter(Mandatory=$false)][String] $UserName, + [Alias("j")][Parameter(Mandatory=$true,ValueFromPipeline=$true)][PSTypeName("CronJob")] $Job #TODO use CronJob type + ) + process { + + [string[]] $crontab = Get-CronTab -user $UserName + [string[]] $newcrontab = $null + $found = $false + + foreach ($line in $crontab) { + $cronjob = ConvertTo-CronJob -crontab $line + if ((Compare-object $cronjob.psobject.properties $Job.psobject.properties) -eq $null) { + $found = $true + } else { + $newcrontab += $line + } + } + + if (-not $found) { + $e = New-Object System.Exception -ArgumentList "Job not found" + throw $e + } + if ($pscmdlet.ShouldProcess($Job.Command,"Remove")) { + Import-CronTab -user $UserName -crontab $newcrontab + } + } +} + +function New-CronJob { +<# +.SYNOPSIS + Create a new cron job +.DESCRIPTION + Create a new job in the cron table. Date and time parameters can be specified + as ranges such as 10-30, as a list: 5,6,7, or combined 1-5,10-15. An asterisk + means 'first through last' (the entire allowed range). Step values can be used + with ranges or with an asterisk. Every 2 hours can be specified as either + 0-23/2 or */2. +.EXAMPLE + New-CronJob -Minute 10-30 -Hour 10-20/2 -DayOfMonth */2 -Command "/bin/bash -c 'echo hello' > ~/hello" +.RETURNVALUE + If successful, an object representing the cron job is returned +.PARAMETER UserName + Optional parameter to specify a specific user's cron table +.PARAMETER Minute + Valid values are 0 to 59. If not specified, defaults to *. +.PARAMETER Hour + Valid values are 0-23. If not specified, defaults to *. +.PARAMETER DayOfMonth + Valid values are 1-31. If not specified, defaults to *. +.PARAMETER Month + Valid values are 1-12. If not specified, defaults to *. +.PARAMETER DayOfWeek + Valid values are 0-7. 0 and 7 are both Sunday. If not specified, defaults to *. +.PARAMETER Command + Command to execute at the scheduled time and day. +#> + [CmdletBinding()] + param ( + [Alias("u")][Parameter(Mandatory=$false)][String] $UserName, + [Alias("mi")][Parameter(Position=1)][String[]] $Minute = "*", + [Alias("h")][Parameter(Position=2)][String[]] $Hour = "*", + [Alias("dm")][Parameter(Position=3)][String[]] $DayOfMonth = "*", + [Alias("mo")][Parameter(Position=4)][String[]] $Month = "*", + [Alias("dw")][Parameter(Position=5)][String[]] $DayOfWeek = "*", + [Alias("c")][Parameter(Mandatory=$true,Position=6)][String] $Command + ) + process { + # TODO: validate parameters, note that different versions of crontab support different capabilities + $line = "{0} {1} {2} {3} {4} {5}" -f [String]::Join(",",$Minute), [String]::Join(",",$Hour), + [String]::Join(",",$DayOfMonth), [String]::Join(",",$Month), [String]::Join(",",$DayOfWeek), $Command + [string[]] $crontab = Get-CronTab -user $UserName + $crontab += $line + Import-CronTab -User $UserName -crontab $crontab + ConvertTo-CronJob -crontab $line + } +} + +function Get-CronJob { +<# +.SYNOPSIS + Returns the current cron jobs from the cron table +.DESCRIPTION + Returns the current cron jobs from the cron table +.EXAMPLE + Get-CronJob -UserName Steve +.RETURNVALUE + CronJob objects +.PARAMETER UserName + Optional parameter to specify a specific user's cron table +#> + [CmdletBinding()] + [OutputType([PSObject])] + param ( + [Alias("u")][Parameter(Mandatory=$false)][String] $UserName + ) + process { + $crontab = Get-CronTab -user $UserName + ForEach ($line in $crontab) { + if ($line.Trim().Length -gt 0) + { + ConvertTo-CronJob -crontab $line + } + } + } +} diff --git a/samples/modules/README.md b/samples/modules/README.md new file mode 100644 index 0000000000..9a7f330f3a --- /dev/null +++ b/samples/modules/README.md @@ -0,0 +1 @@ +# Samples From 46199198725c79824c31a6394803f1b20b0cb7d3 Mon Sep 17 00:00:00 2001 From: joeyaiello Date: Tue, 12 Jul 2016 17:09:55 -0700 Subject: [PATCH 4/4] move sample modules into demos --- .../ApacheHTTPServer/ApacheVirtualHosts.psm1 | 0 {samples => demos}/modules/CronTab/CronTab.ps1xml | 0 {samples => demos}/modules/CronTab/CronTab.psd1 | Bin {samples => demos}/modules/CronTab/CronTab.psm1 | 0 {samples => demos}/modules/README.md | 0 5 files changed, 0 insertions(+), 0 deletions(-) rename {samples => demos}/modules/ApacheHTTPServer/ApacheVirtualHosts.psm1 (100%) rename {samples => demos}/modules/CronTab/CronTab.ps1xml (100%) rename {samples => demos}/modules/CronTab/CronTab.psd1 (100%) rename {samples => demos}/modules/CronTab/CronTab.psm1 (100%) rename {samples => demos}/modules/README.md (100%) diff --git a/samples/modules/ApacheHTTPServer/ApacheVirtualHosts.psm1 b/demos/modules/ApacheHTTPServer/ApacheVirtualHosts.psm1 similarity index 100% rename from samples/modules/ApacheHTTPServer/ApacheVirtualHosts.psm1 rename to demos/modules/ApacheHTTPServer/ApacheVirtualHosts.psm1 diff --git a/samples/modules/CronTab/CronTab.ps1xml b/demos/modules/CronTab/CronTab.ps1xml similarity index 100% rename from samples/modules/CronTab/CronTab.ps1xml rename to demos/modules/CronTab/CronTab.ps1xml diff --git a/samples/modules/CronTab/CronTab.psd1 b/demos/modules/CronTab/CronTab.psd1 similarity index 100% rename from samples/modules/CronTab/CronTab.psd1 rename to demos/modules/CronTab/CronTab.psd1 diff --git a/samples/modules/CronTab/CronTab.psm1 b/demos/modules/CronTab/CronTab.psm1 similarity index 100% rename from samples/modules/CronTab/CronTab.psm1 rename to demos/modules/CronTab/CronTab.psm1 diff --git a/samples/modules/README.md b/demos/modules/README.md similarity index 100% rename from samples/modules/README.md rename to demos/modules/README.md