Advertisement
martinevans

Spinning Plates and Slaying Vampires with PowerShell

Nov 12th, 2013
134
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. <#
  2. Useful links from the talk :
  3. PowerGUI: http://www.quest.com/powergui-freeware/
  4. Hey Scripting Guy! : http://blogs.technet.com/b/heyscriptingguy/
  5.  
  6.  
  7. GO FORTH AND AUTOMATE!
  8. @martin_evans
  9. http://about.me/martin.evans
  10.  
  11. #> 
  12.  
  13. <#
  14. This is the full module (psm1 file) we build in the "Spinning Plates and Slaying Vampires With PowerShell" talk.
  15.    
  16.     There are a couple of environment variables that need setting up for this to work - I've added a function in this file called Set-UserEnvironmentVariable to assist you
  17.     "casesFolder" - folder location where all your case notes would be stored
  18.     "solutionRootFolder" - folder location in which different versions of your solution would be stored.
  19.     "localRepo" - folder location of your patch repository - each patch is an sql file named numerically i.e. 1001.sql etc
  20.    
  21.     Type "Get-Help Set-UserEnvironmentVariable -detailed" for more info. Also, have a look at how the I've bound the help text to the Set-UserEnvironmentVariable function below.
  22.    
  23.     In the GetDB Connection you must supply the $ServerName and $DatabaseName values for your local sql server instance
  24.                
  25.  #>
  26.  
  27. # This line replaces the now deprecated LoadWithPartialName method I mentioned last night
  28. Add-Type -AssemblyName "System.Data"
  29.  
  30. function Get-Case(){
  31.     param(
  32.         [Parameter(Mandatory=$true)]
  33.         [ValidatePattern('^[0-9]{3,4}$')] [int]$caseNumber
  34.     )
  35.    
  36.     $folders = gci -Path $env:casesFolder -Filter  "$caseNumber*"
  37.    
  38.     if($folders.length -gt 1){
  39.         Write-Warning "Multiple case folders found containing $caseNumber";
  40.         return;  
  41.     }
  42.  
  43.     if($folders.length -eq 0) {
  44.          ni -Type directory -Path "$env:casesFolder" -name $caseNumber;
  45.          $folder = "$env:casesFolder\$caseNumber";
  46.     }
  47.     else {
  48.         $folder = "$env:casesFolder\$folders";
  49.     }
  50.    
  51.     $notesFile = "$folder\Notes.txt";
  52.    
  53.     if((Test-Path $notesFile) -eq $false){
  54.         "Case notes for $caseNumber" >> $notesFile;
  55.     }
  56.        
  57.     #start "https://you_case_logging_url.com?$caseNumber"
  58.     Invoke-Item $notesFile
  59. }
  60.  
  61. function Get-MyApp() {
  62.     param([parameter(mandatory=$true)]
  63.             [ValidateSet("DEV","UAT","PROD")]
  64.             $ver)      
  65.     gci -Path "$env:solutionRootFolder\$ver\myimportantapp"  -Filter "*.sln" | ii
  66. }
  67.  
  68. function Install-Patch() {
  69.     Param([Parameter(Mandatory=$true)]
  70.             [int[]]$patchNumbers)
  71.        
  72.         Push-Location $env:localRepo
  73.        
  74.         # If your local repo doesnt synch from anywhere, I'd comment out the line below!
  75.         hg pull -u
  76.        
  77.         $conn = Get-OpenDbConnection
  78.    
  79.         foreach ($patchNumber in $patchNumbers)
  80.         {                  
  81.             $file = Get-FileMatchingCriteria $patchNumber
  82.            
  83.             if ($file){
  84.                     "Running Patch $patchNumber"
  85.                     $cmdTxt = Get-Content $file
  86.                     if($pscmdlet.ShouldProcess($patchNumber)){
  87.                         ExecuteCommand $cmdTxt $conn
  88.                     }
  89.                     else
  90.                     {
  91.                         $cmdTxt
  92.                     }
  93.             }
  94.         }
  95.        
  96.         $conn.Close();
  97.         $conn.Dispose();   
  98.         Pop-Location
  99. }
  100.  
  101. function Get-OpenDbConnection(){
  102.     $ServerName = "localhost"
  103.     $DatabaseName="OneDbToRuleThemAll"
  104.    
  105.     $connStr = [System.String]::Format("Data Source={0};Initial Catalog={1};Integrated Security=SSPI", $ServerName, $DatabaseName)
  106.     $conn = New-Object System.Data.SqlClient.SqlConnection($connStr)
  107.    
  108.     # $action is a script block we hook up to the InfoMessage eevent on the connection
  109.     $action = { Write-Host $event.sourceEventArgs.Message -foregroundcolor "magenta"}  
  110.     Register-ObjectEvent  -InputObject $conn -EventName InfoMessage -Action $action | Out-Null
  111.    
  112.     $conn.Open()
  113.     return $conn;
  114. }
  115.  
  116. function ExecuteCommand($cmdTxt, $conn){
  117.     $cmd = New-Object System.Data.SqlClient.SqlCommand($cmdTxt, $conn)
  118.     $cmd.ExecuteNonQuery() | Out-Null
  119.     $cmd.Dispose()
  120. }
  121.  
  122. function Get-FileMatchingCriteria($patchNumber) {  
  123.     $file = Get-ChildItem . -include "*$patchNumber.sql" -Path "$env:localRepo" -Recurse;                                                  
  124.     if($file -eq $null) {
  125.         Write-Host "Unable to find patch $patchNumber" -foregroundcolor "magenta";
  126.         return $null;
  127.     }
  128.     elseif ($file.count -gt 1) {                            
  129.         Write-Host "Multiple patches ending in $patchNumber found. Please investigate." -foregroundcolor "magenta";
  130.         return $null;
  131.     }
  132.     return $file;
  133. }
  134.  
  135. function Find-Patch{
  136.         param([string] [ValidatePattern('^[a-z]{3,}$')] $criteria)
  137.         gci $env:localrepo -filter "*.sql" | select-string $criteria    
  138.     }
  139.    
  140. function Show-Patch{
  141.             param(
  142.                 [string] [ValidatePattern('^[0-9]{3,4}$')] $patchNumber,
  143.                 [switch] $showInNotePad
  144.             )
  145.        
  146.     $file = Get-FileMatchingCriteria $patchNumber
  147.        
  148.     if($file) {            
  149.         if($showInNotePad -eq $true){
  150.             notepad $file
  151.         }
  152.         else {
  153.             Get-Content $file  | Write-Host
  154.         }                                          
  155.     }
  156. }
  157.  
  158. <#
  159.     .SYNOPSIS
  160.         Sets a user environment variable
  161.  
  162.     .DESCRIPTION
  163.         This function sets a user environment variable on the local machine. This variable will only be available to the logged in user
  164.  
  165.     .PARAMETER  Name
  166.         The name of the variable
  167.  
  168.     .PARAMETER  Value
  169.         The value of the variable you have set.
  170.  
  171.     .EXAMPLE
  172.         PS C:\> Set-UserEnvironmentVariable  casesFolder "C:\MyCases"
  173.  
  174.     .INPUTS
  175.         System.String,System.String
  176.  
  177.     .OUTPUTS
  178.         System.String
  179.  
  180.     .NOTES
  181.         To override the value of an existing variable, call the function again, supplying the variable name and the new value .
  182.         To remove the environment variable call the function again, supplying the variable name and $null as the value.
  183.    
  184. #>
  185. function Set-UserEnvironmentVariable($name, $value){
  186.     [Environment]::SetEnvironmentVariable("$name",$value,"User")
  187. }
  188.  
  189. <#
  190.     .SYNOPSIS
  191.         Allows you to switch between one version of an app with another within the same instance of Visual Studio
  192.  
  193.     .DESCRIPTION
  194.         I call this function when I need to switch from a dev version of an app to a version of the solution that is currently in test ot even in production.
  195.         The convention being that I will have each version of the code in a dev, uat or prod folder within a the folder named in my $env:solutionRootFolder value
  196.  
  197.     .PARAMETER  version
  198.         The version of the code I wish to load in VS
  199.        
  200.     .EXAMPLE
  201.         Open-MyApp PROD
  202.  
  203.     .INPUTS
  204.         System.String
  205.  
  206.     .NOTES
  207.        
  208.  
  209.     .LINK
  210.         about_functions_advanced
  211.  
  212.     .LINK
  213.         about_comment_based_help
  214.  
  215. #>
  216. function Open-MyApp($version)
  217. {
  218.     if($dte){
  219.         $solution = $dte.solution; 
  220.         $solution.Open("$env:solutionRootFolder\$version\myimportantapp\myimportantapp.sln");
  221.         set-location "$env:demoAppRootFolder\myapp\$version"
  222.     }
  223.     else {
  224.         "This function needs to be called from within Visual Studio"
  225.     }
  226. }
  227.  
  228. Set-Alias oma Open-MyApp -Description "Opens my app in the current version of visual studio"
  229. Set-Alias case Get-Case -Description "Opens case notes and details in fb for the specified case notes"
  230. Set-Alias instp Install-Patch -Description "Install database patch"
  231. Set-Alias findp Find-Patch -Description "Searches for all all patches containing the supplied criteria"
  232. Set-Alias showp Show-Patch -Description "Displays a patch"
  233. Set-Alias app Get-MyApp -Description "Loads my app in visual studio"
  234. Set-Alias sue Set-UserEnvironmentVariable -Description "Allows you to set a user environment variable"
  235.  
  236. export-modulemember -alias * -function Install-Patch, Find-Patch, Show-Patch, Get-MyApp, Get-Case, Set-UserEnvironmentVariable, Open-MyApp
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement