├── LICENSE.txt ├── 9781484205426.jpg ├── PPSFDD ├── Data │ ├── Customers.txt │ ├── psappconfig.csv │ ├── psappconfig.txt │ ├── script_revised.sql │ ├── create_partition_table.sql │ ├── psappconfig │ │ ├── psappconfig.csv │ │ └── psappconfig.txt │ ├── sales_abccompany_20141101.zip │ ├── columnmapping.csv │ ├── script.sql │ ├── StateSalesTaxRates.csv │ ├── create_table_1.sql │ ├── test.txt │ ├── somedata.txt │ ├── Employees.txt │ ├── state_table.csv │ └── currencyexchangerate.csv ├── Listings │ ├── Chapter10 │ │ ├── listing-10-18.ps1 │ │ ├── listing-10-20.ps1 │ │ ├── listing-10-19.ps1 │ │ ├── psappconfig.txt │ │ ├── listing-10-13.txt │ │ ├── listing-10-4.txt │ │ ├── listing-10-9.sql │ │ ├── listing-10-2.ps1 │ │ ├── listing-10-6.csv │ │ ├── listing-10-14.ps1 │ │ ├── listing-10-3.ps1 │ │ ├── listing-10-8.ps1 │ │ ├── listing-10-12.ps1 │ │ ├── listing-10-5.ps1 │ │ ├── listing-10-15.ps1 │ │ ├── listing-10-17.ps1 │ │ ├── listing-10-7.ps1 │ │ ├── listing-10-10.sql │ │ ├── listing-10-16.ps1 │ │ ├── listing-10-11.ps1 │ │ ├── listing-10-21.ps1 │ │ └── listing-10-1.ps1 │ ├── Chapter02 │ │ ├── listing-2-1.ps1 │ │ ├── listing-2-6.ps1 │ │ ├── listing-2-4.ps1 │ │ ├── listing-2-11.ps1 │ │ ├── listing-2-10.ps1 │ │ ├── listing-2-7.ps1 │ │ ├── listing-2-8.ps1 │ │ ├── listing-2-9.ps1 │ │ ├── listing-2-2.ps1 │ │ ├── listing-2-3.ps1 │ │ └── listing-2-5.ps1 │ ├── Chapter11 │ │ ├── listing-11-1.sql │ │ ├── listing-11-3.ps1 │ │ ├── listing-11-5.sql │ │ ├── listing-11-6.sql │ │ ├── listing-11-4.sql │ │ └── listing-11-2.ps1 │ ├── Chapter04 │ │ ├── listing-4-9.ps1 │ │ ├── listing-4-10.ps1 │ │ ├── listing-4-3.ps1 │ │ ├── listing-4-2.ps1 │ │ ├── listing-4-4.ps1 │ │ ├── listing-4-5.sql │ │ ├── listing-4-7.ps1 │ │ ├── listing-4-12.ps1 │ │ ├── listing-4-8.ps1 │ │ ├── listing-4-6.ps1 │ │ ├── listing-4-1.ps1 │ │ ├── listing-4-13.ps1 │ │ └── listing-4-11.ps1 │ ├── Chapter13 │ │ ├── listing-13-2.ps1 │ │ ├── listing-13-9.ps1 │ │ ├── listing-13-10.ps1 │ │ ├── listing-13-3.ps1 │ │ ├── listing-13-4.ps1 │ │ ├── listing-13-1.ps1 │ │ ├── listing-13-7.ps1 │ │ ├── listing-13-13.ps1 │ │ ├── listing-13-6.ps1 │ │ ├── listing-13-12.ps1 │ │ ├── listing-13-5.ps1 │ │ ├── listing-13-8.ps1 │ │ ├── listing-13-11.ps1 │ │ ├── listing-13-14.ps1 │ │ └── listing-13-15.ps1 │ ├── Chapter08 │ │ ├── listing-8-4.ps1 │ │ ├── listing-8-7.ps1 │ │ ├── listing-8-10.ps1 │ │ ├── listing-8-9.ps1 │ │ ├── listing-8-11.ps1 │ │ ├── listing-8-2.ps1 │ │ ├── listing-8-5.ps1 │ │ ├── listing-8-8.ps1 │ │ ├── listing-8-3.ps1 │ │ ├── listing-8-1.ps1 │ │ └── listing-8-6.ps1 │ ├── Chapter05 │ │ ├── listing-5-29.ps1 │ │ ├── listing-5-30.ps1 │ │ ├── listing-5-27.ps1 │ │ ├── listing-5-28.ps1 │ │ ├── listing-5-25.ps1 │ │ ├── listing-5-26.ps1 │ │ ├── translate │ │ │ ├── es-ES │ │ │ │ └── translate.psd1 │ │ │ ├── en-US │ │ │ │ └── translate.psd1 │ │ │ ├── de-DE │ │ │ │ └── translate.psd1 │ │ │ └── translate.ps1 │ │ ├── listing-5-2.ps1 │ │ ├── Simple_NoCmdletBinding.ps1 │ │ ├── listing-5-8.ps1 │ │ ├── Simple_CmdletBinding.ps1 │ │ ├── listing-5-10.ps1 │ │ ├── listing-5-9.ps1 │ │ ├── listing-5-4.ps1 │ │ ├── listing-5-22.ps1 │ │ ├── listing-5-3.ps1 │ │ ├── listing-5-5.ps1 │ │ ├── listing-5-11.ps1 │ │ ├── listing-5-14.ps1 │ │ ├── listing-5-21.ps1 │ │ ├── listing-5-7.ps1 │ │ ├── listing-5-12.ps1 │ │ ├── listing-5-6.ps1 │ │ ├── listing-5-17.ps1 │ │ ├── listing-5-19.ps1 │ │ ├── listing-5-15.ps1 │ │ ├── listing-5-16.ps1 │ │ ├── listing-5-18.ps1 │ │ ├── listing-5-20.ps1 │ │ ├── listing-5-1.ps1 │ │ ├── listing-5-23.ps1 │ │ ├── listing-5-13.ps1 │ │ └── listing-5-24.ps1 │ ├── Chapter03 │ │ ├── scr_openfiledlg.ps1 │ │ ├── scr_openfiledlg_with_parms.ps1 │ │ ├── listing-3-12.ps1 │ │ ├── listing-3-7.ps1 │ │ ├── listing-3-11.ps1 │ │ ├── listing-3-13.ps1 │ │ ├── scr_openfiledlg_with_parms_andswitches.ps1 │ │ ├── listing-3-1.ps1 │ │ ├── listing-3-5.ps1 │ │ ├── listing-3-10.ps1 │ │ ├── listing-3-9.ps1 │ │ ├── listing-3-6.ps1 │ │ ├── listing-3-2.ps1 │ │ ├── listing-3-8.ps1 │ │ ├── listing-3-3.ps1 │ │ └── listing-3-4.ps1 │ ├── Chapter06 │ │ ├── listing-6-1.ps1 │ │ ├── listing-6-2.ps1 │ │ ├── listing-6-3.ps1 │ │ ├── listing-6-5.ps1 │ │ └── listing-6-4.ps1 │ ├── Chapter07 │ │ ├── listing-7-5.sql │ │ ├── listing-7-2.sql │ │ ├── listing-7-3.ps1 │ │ ├── listing-7-1.ps1 │ │ ├── listing-7-7.ps1 │ │ ├── listing-7-4.sql │ │ ├── listing-7-8.ps1 │ │ └── listing-7-6.ps1 │ ├── Chapter12 │ │ ├── listing-12-2.ps1 │ │ └── listing-12-1.ps1 │ └── Chapter09 │ │ └── listing-9-1.ps1 ├── Modules │ ├── umd_appconfig │ │ ├── psappconfig.txt │ │ └── umd_appconfig.psm1 │ ├── umd_application │ │ ├── function │ │ │ ├── Invoke-UdfAddNumber.ps1 │ │ │ ├── Invoke-UdfMultiplyNumber.ps1 │ │ │ └── Invoke-UdfSubtractNumber.ps1 │ │ └── umd_application.psm1 │ ├── umd_ModuleParms │ │ ├── Invoke-UdfSubtractNumber.ps1 │ │ ├── Invoke-UdfMultiplyNumber.ps1 │ │ ├── Invoke-UdfAddNumber.ps1 │ │ └── umd_ModuleParms.psm1 │ ├── umd_database │ │ ├── xxxx.ps1 │ │ ├── scr_wf_as_scheduled_job.ps1 │ │ ├── connectionstrings.txt │ │ └── scr_load_products.ps1 │ ├── umd_filesearch │ │ └── umd_filesearch.psm1 │ ├── umd_Simple │ │ ├── scr_test.ps1 │ │ ├── umd_Simple_withexport.psm1 │ │ └── umd_Simple.psm1 │ ├── umd_ModuleDotSource │ │ ├── ufn_add_numbers.ps1 │ │ ├── ufn_subtract_numbers.ps1 │ │ └── umd_ModuleDotSource.psm1 │ ├── umd_Simple_withexport │ │ └── umd_Simple_withexport.psm1 │ ├── umd_state │ │ └── umd_state.psm1 │ ├── umd_jobs │ │ └── umd_jobs.psm1 │ ├── umd_workflow │ │ └── umd_workflow.psm1 │ ├── umd_etl │ │ └── umd_etl.psm1 │ ├── umd_join_object │ │ └── umd_join_object.psm1 │ └── umd_northwind_etl │ │ └── umd_northwind_etl.psm1 └── ReadMe.txt ├── README.md └── contributing.md /LICENSE.txt: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Apress/pro-powershell-for-db-devs/HEAD/LICENSE.txt -------------------------------------------------------------------------------- /9781484205426.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Apress/pro-powershell-for-db-devs/HEAD/9781484205426.jpg -------------------------------------------------------------------------------- /PPSFDD/Data/Customers.txt: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Apress/pro-powershell-for-db-devs/HEAD/PPSFDD/Data/Customers.txt -------------------------------------------------------------------------------- /PPSFDD/Data/psappconfig.csv: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Apress/pro-powershell-for-db-devs/HEAD/PPSFDD/Data/psappconfig.csv -------------------------------------------------------------------------------- /PPSFDD/Data/psappconfig.txt: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Apress/pro-powershell-for-db-devs/HEAD/PPSFDD/Data/psappconfig.txt -------------------------------------------------------------------------------- /PPSFDD/Data/script_revised.sql: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Apress/pro-powershell-for-db-devs/HEAD/PPSFDD/Data/script_revised.sql -------------------------------------------------------------------------------- /PPSFDD/Data/create_partition_table.sql: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Apress/pro-powershell-for-db-devs/HEAD/PPSFDD/Data/create_partition_table.sql -------------------------------------------------------------------------------- /PPSFDD/Data/psappconfig/psappconfig.csv: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Apress/pro-powershell-for-db-devs/HEAD/PPSFDD/Data/psappconfig/psappconfig.csv -------------------------------------------------------------------------------- /PPSFDD/Data/psappconfig/psappconfig.txt: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Apress/pro-powershell-for-db-devs/HEAD/PPSFDD/Data/psappconfig/psappconfig.txt -------------------------------------------------------------------------------- /PPSFDD/Data/sales_abccompany_20141101.zip: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Apress/pro-powershell-for-db-devs/HEAD/PPSFDD/Data/sales_abccompany_20141101.zip -------------------------------------------------------------------------------- /PPSFDD/Listings/Chapter10/listing-10-18.ps1: -------------------------------------------------------------------------------- 1 | function Invoke-UdfAddNumber([int]$p_int1, [int]$p_int2) 2 | { 3 | Return ($p_int1 + $p_int2) 4 | } 5 | -------------------------------------------------------------------------------- /PPSFDD/Listings/Chapter10/listing-10-20.ps1: -------------------------------------------------------------------------------- 1 | function Invoke-UdfMultiplyNumber([int]$p_int1, [int]$p_int2) 2 | { 3 | Return ($p_int1 * $p_int2) 4 | } 5 | -------------------------------------------------------------------------------- /PPSFDD/Modules/umd_appconfig/psappconfig.txt: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Apress/pro-powershell-for-db-devs/HEAD/PPSFDD/Modules/umd_appconfig/psappconfig.txt -------------------------------------------------------------------------------- /PPSFDD/Data/columnmapping.csv: -------------------------------------------------------------------------------- 1 | SourceColumn,TargetColumn 2 | DepartmentID,UnitID 3 | [Name],[UnitName] 4 | GroupName,UnitGroupName 5 | ModifiedDate,UpdateDate 6 | -------------------------------------------------------------------------------- /PPSFDD/Listings/Chapter10/listing-10-19.ps1: -------------------------------------------------------------------------------- 1 | 2 | function Invoke-UdfSubtractNumber([int]$p_int1, [int]$p_int2) 3 | { 4 | Return ($p_int1 - $p_int2) 5 | } 6 | -------------------------------------------------------------------------------- /PPSFDD/Modules/umd_application/function/Invoke-UdfAddNumber.ps1: -------------------------------------------------------------------------------- 1 | function Invoke-UdfAddNumber([int]$p_int1, [int]$p_int2) 2 | { 3 | Return ($p_int1 + $p_int2) 4 | } 5 | -------------------------------------------------------------------------------- /PPSFDD/Modules/umd_application/function/Invoke-UdfMultiplyNumber.ps1: -------------------------------------------------------------------------------- 1 | function Invoke-UdfMultiplyNumber([int]$p_int1, [int]$p_int2) 2 | { 3 | Return ($p_int1 * $p_int2) 4 | } 5 | -------------------------------------------------------------------------------- /PPSFDD/Modules/umd_application/function/Invoke-UdfSubtractNumber.ps1: -------------------------------------------------------------------------------- 1 | function Invoke-UdfSubtractNumber([int]$p_int1, [int]$p_int2) 2 | { 3 | Return ($p_int1 - $p_int2) 4 | } 5 | -------------------------------------------------------------------------------- /PPSFDD/Listings/Chapter02/listing-2-1.ps1: -------------------------------------------------------------------------------- 1 | Set-Location $env:USERPROFILE 2 | 3 | @" 4 | This is just a file 5 | stuff1 6 | stuff2 7 | lastline 8 | "@ > "$env:USERPROFILE\file1.txt" 9 | 10 | 11 | 12 | -------------------------------------------------------------------------------- /PPSFDD/Listings/Chapter02/listing-2-6.ps1: -------------------------------------------------------------------------------- 1 | # Create a file... 2 | "this is a test file created for demostration purposes" > infilepsbook.txt 3 | 4 | $myfile = Get-Content infilepsbook.txt 5 | 6 | $myfile 7 | -------------------------------------------------------------------------------- /PPSFDD/Listings/Chapter11/listing-11-1.sql: -------------------------------------------------------------------------------- 1 | CREATE TABLE [dbo].[StateSalesTaxRate]( 2 | [StateProvinceCD] [varchar](255) NULL, 3 | [StateProvinceSalesTaxRate] [decimal](5, 2) NULL, 4 | [CreateDate] [datetime] NULL 5 | ) 6 | -------------------------------------------------------------------------------- /PPSFDD/Listings/Chapter04/listing-4-9.ps1: -------------------------------------------------------------------------------- 1 | for($i=1; $i -le 2; $i++) { 2 | Get-Process -Id 255 -ErrorAction SilentlyContinue -ErrorVariable hold 3 | "Loop Iteration: $i" 4 | } 5 | write-host "`r`nError Varibale contains..." 6 | $hold 7 | -------------------------------------------------------------------------------- /PPSFDD/Listings/Chapter11/listing-11-3.ps1: -------------------------------------------------------------------------------- 1 | Import-Module umd_etl_functions 2 | 3 | $salestax = Import-CSV ($env:HomeDrive + $env:HOMEPATH + "\Documents\StateSalesTaxRates.csv") 4 | $salestax | Invoke-UdfStateTaxFileTransformation 5 | -------------------------------------------------------------------------------- /PPSFDD/Listings/Chapter13/listing-13-2.ps1: -------------------------------------------------------------------------------- 1 | workflow simple ([string] $myparm) 2 | { 3 | "Parameter is $myparm" 4 | 5 | Get-Date 6 | 7 | "Some activity" 8 | 9 | "Third activity" 10 | } 11 | 12 | simple "test" 13 | -------------------------------------------------------------------------------- /PPSFDD/Listings/Chapter13/listing-13-9.ps1: -------------------------------------------------------------------------------- 1 | workflow Invoke-UdwSimpleSequence ([string] $myparm) 2 | { 3 | sequence 4 | { 5 | "First" 6 | "Second" 7 | "Third" 8 | } 9 | } 10 | 11 | Invoke-UdwSimpleSequence 12 | -------------------------------------------------------------------------------- /PPSFDD/Listings/Chapter02/listing-2-4.ps1: -------------------------------------------------------------------------------- 1 | $myvar = "Bryan" 2 | 3 | $myherestring = @" 4 | " Four score and $ * 5 | 6 | Seven years… ,,, ~` ‘ ago 7 | 8 | $myvar 9 | 10 | ! 11 | " 12 | "@ 13 | 14 | Write-Host $myherestring 15 | -------------------------------------------------------------------------------- /PPSFDD/Listings/Chapter04/listing-4-10.ps1: -------------------------------------------------------------------------------- 1 | for($i=1; $i -le 2; $i++) { 2 | Get-Process -Id 255 -ErrorAction SilentlyContinue -ErrorVariable +hold 3 | "Loop Iteration: $i" 4 | } 5 | write-host "`r`nError Varibale contains..." 6 | $hold 7 | -------------------------------------------------------------------------------- /PPSFDD/Listings/Chapter08/listing-8-4.ps1: -------------------------------------------------------------------------------- 1 | function Invoke-UdfMyFunction ([string]$parm1, [int]$parm2, $parm3 ) 2 | { 3 | 4 | $MyInvocation 5 | 6 | # Do some work... 7 | } 8 | 9 | Invoke-UdfMyFunction "test" 1 "something" 10 | -------------------------------------------------------------------------------- /PPSFDD/Modules/umd_ModuleParms/Invoke-UdfSubtractNumber.ps1: -------------------------------------------------------------------------------- 1 | function Invoke-UdfSubtractNumber([int]$p_int1, [int]$p_int2) 2 | { 3 | Return ($p_int1 - $p_int2) 4 | } 5 | 6 | # Example Function Calls... 7 | # 8 | # Invoke-UdfSubtractNumber 4 1 -------------------------------------------------------------------------------- /PPSFDD/Listings/Chapter05/listing-5-29.ps1: -------------------------------------------------------------------------------- 1 | Import-LocalizedData -BindingVariable ds -UICulture de-DE # German 2 | 3 | $ds.Sunday 4 | $ds.Monday 5 | $ds.Tuesday 6 | $ds.Wednesday 7 | $ds.Thursday 8 | $ds.Friday 9 | $ds.Saturday 10 | -------------------------------------------------------------------------------- /PPSFDD/Listings/Chapter05/listing-5-30.ps1: -------------------------------------------------------------------------------- 1 | Import-LocalizedData -BindingVariable ds -UICulture es-ES # Spanish 2 | 3 | $ds.Sunday 4 | $ds.Monday 5 | $ds.Tuesday 6 | $ds.Wednesday 7 | $ds.Thursday 8 | $ds.Friday 9 | $ds.Saturday 10 | -------------------------------------------------------------------------------- /PPSFDD/Modules/umd_ModuleParms/Invoke-UdfMultiplyNumber.ps1: -------------------------------------------------------------------------------- 1 | # Simple module example 2 | 3 | function Invoke-UdfMultiplyNumber([int]$p_int1, [int]$p_int2) 4 | { 5 | Return ($p_int1 * $p_int2) 6 | } 7 | 8 | # Example Call : Invoke-UdfMultiplyNumber 5 4 9 | -------------------------------------------------------------------------------- /PPSFDD/Listings/Chapter05/listing-5-27.ps1: -------------------------------------------------------------------------------- 1 | # Folder: es-ES 2 | ConvertFrom-StringData @" 3 | Sunday=domingo 4 | Monday=lunes 5 | Tuesday=martes 6 | Wednesday=miércoles 7 | Thursday=jueves 8 | Friday=viernes 9 | Saturday=sábado 10 | "@ 11 | -------------------------------------------------------------------------------- /PPSFDD/Listings/Chapter05/listing-5-28.ps1: -------------------------------------------------------------------------------- 1 | Import-LocalizedData -BindingVariable ds # Machine Default - English 2 | 3 | $ds.Sunday 4 | $ds.Monday 5 | $ds.Tuesday 6 | $ds.Wednesday 7 | $ds.Thursday 8 | $ds.Friday 9 | $ds.Saturday 10 | -------------------------------------------------------------------------------- /PPSFDD/Listings/Chapter05/listing-5-25.ps1: -------------------------------------------------------------------------------- 1 | # Folder: en-US 2 | ConvertFrom-StringData @" 3 | Sunday=Sunday 4 | Monday=Monday 5 | Tuesday=Tuesday 6 | Wednesday=Wednesday 7 | Thursday=Thursday 8 | Friday=Friday 9 | Saturday=Saturday 10 | "@ 11 | -------------------------------------------------------------------------------- /PPSFDD/Modules/umd_ModuleParms/Invoke-UdfAddNumber.ps1: -------------------------------------------------------------------------------- 1 | # Simple module example 2 | 3 | function Invoke-UdfAddNumber([int]$p_int1, [int]$p_int2) 4 | { 5 | Return ($p_int1 + $p_int2) 6 | } 7 | 8 | # Example Function Calls... 9 | # 10 | # Invoke-UdfAddNumber 1 4 11 | -------------------------------------------------------------------------------- /PPSFDD/Listings/Chapter02/listing-2-11.ps1: -------------------------------------------------------------------------------- 1 | # Create an array of integers… 2 | $array = (1,2,3,4,5) 3 | foreach ($item in $array) {write-Host $item} 4 | 5 | # Create an array of strings.. 6 | $array = ("Mary","Joe","Tom","Harry","Lisa") 7 | foreach ($item in $array) {write-Host $item} 8 | -------------------------------------------------------------------------------- /PPSFDD/Listings/Chapter05/listing-5-26.ps1: -------------------------------------------------------------------------------- 1 | # Folder: de-DE 2 | ConvertFrom-StringData @" 3 | Sunday=Sonntag; 4 | Monday=Montag; 5 | Tuesday=Deinstag; 6 | Wednesday=Mittwoch; 7 | Thursday=Donnerstag; 8 | Friday=Freitag; 9 | Saturday=Samstag 10 | "@ 11 | -------------------------------------------------------------------------------- /PPSFDD/Listings/Chapter05/translate/es-ES/translate.psd1: -------------------------------------------------------------------------------- 1 | # Folder: es-ES 2 | ConvertFrom-StringData @" 3 | Sunday=domingo 4 | Monday=lunes 5 | Tuesday=martes 6 | Wednesday=miércoles 7 | Thursday=jueves 8 | Friday=viernes 9 | Saturday=sábado 10 | "@ 11 | -------------------------------------------------------------------------------- /PPSFDD/Listings/Chapter13/listing-13-10.ps1: -------------------------------------------------------------------------------- 1 | workflow Invoke-UdwForeachparallel 2 | { 3 | 4 | $collection = "one","two","three" 5 | 6 | foreach -parallel ($item in $collection) 7 | { 8 | "Length is: " + $item.Length 9 | } 10 | } 11 | 12 | Invoke-UdwForeachparallel 13 | -------------------------------------------------------------------------------- /PPSFDD/Modules/umd_database/xxxx.ps1: -------------------------------------------------------------------------------- 1 | function Find-NewMessages($valvar1, [REF]$refvar1, [REF]$refvar2) { 2 | #//some stuff 3 | $refvar1.Value = “hi” 4 | $refvar2.Value = “bye” 5 | } 6 | 7 | $refvar1 = “1” 8 | $refvar2 = “2” 9 | Find-NewMessages $valvar1 ([REF]$refvar1) ([REF]$refvar2) -------------------------------------------------------------------------------- /PPSFDD/Listings/Chapter05/translate/en-US/translate.psd1: -------------------------------------------------------------------------------- 1 | # Folder: en-US 2 | ConvertFrom-StringData @" 3 | Sunday=Sunday 4 | Monday=Monday 5 | Tuesday=Tuesday 6 | Wednesday=Wednesday 7 | Thursday=Thursday 8 | Friday=Friday 9 | Saturday=Saturday 10 | "@ 11 | -------------------------------------------------------------------------------- /PPSFDD/Listings/Chapter05/translate/de-DE/translate.psd1: -------------------------------------------------------------------------------- 1 | # Folder: de-DE 2 | ConvertFrom-StringData @" 3 | Sunday=Sonntag; 4 | Monday=Montag; 5 | Tuesday=Deinstag; 6 | Wednesday=Mittwoch; 7 | Thursday=Donnerstag; 8 | Friday=Freitag; 9 | Saturday=Samstag 10 | "@ 11 | -------------------------------------------------------------------------------- /PPSFDD/Listings/Chapter05/listing-5-2.ps1: -------------------------------------------------------------------------------- 1 | function Invoke-UdfGetHelp 2 | { 3 | [cmdletBinding(HelpURI="http://www.microsoft.com/en-us/default.aspx")] 4 | param ( 5 | ) 6 | 7 | Write-Host "Just to show the HelpURI attribute." 8 | } 9 | 10 | Get-Help -Online Invoke-UdfHelp -------------------------------------------------------------------------------- /PPSFDD/Listings/Chapter10/psappconfig.txt: -------------------------------------------------------------------------------- 1 | emailserver=smtp.live.com 2 | emailaccount=someacct@msn.com 3 | emailfrom=someemail@msn.com 4 | emailpw=somepassword 5 | edwteamemail=edwteam@msn.com 6 | emailport=587 7 | ftpinpath=\\\\ftp\\inbound\\ 8 | ftpoutpath=\\\\ftp\\outbound\\ 9 | edwserver=(local) 10 | -------------------------------------------------------------------------------- /PPSFDD/Listings/Chapter10/listing-10-13.txt: -------------------------------------------------------------------------------- 1 | emailserver=smtp.live.com 2 | emailaccount=someacct@msn.com 3 | emailfrom=someemail@msn.com 4 | emailpw=somepassword 5 | edwteamemail=edwteam@msn.com 6 | emailport=587 7 | ftpinpath=\\\\ftp\\inbound\\ 8 | ftpoutpath=\\\\ftp\\outbound\\ 9 | edwserver=(local) 10 | -------------------------------------------------------------------------------- /PPSFDD/Listings/Chapter10/listing-10-4.txt: -------------------------------------------------------------------------------- 1 | emailserver=smtp.live.com 2 | emailaccount=someacct@msn.com 3 | emailfrom=someemail@msn.com 4 | emailpw=somepassword 5 | edwteamemail=edwteam@msn.com 6 | emailport=587 7 | ftpinpath=\\\\ftp\\inbound\\ 8 | ftpoutpath=\\\\ftp\\outbound\\ 9 | edwserver=(local) 10 | -------------------------------------------------------------------------------- /PPSFDD/Listings/Chapter04/listing-4-3.ps1: -------------------------------------------------------------------------------- 1 | trap { "Error Occurred: $Error." } 2 | Get-Content "nosuchfile" -ErrorAction Stop 3 | 4 | "The script continues..." 5 | 6 | trap { "Another Error Occurred: $Error."; Break } 7 | 8 | Get-Content "nosuchfile" -ErrorAction Stop 9 | 10 | "This line will still execute" 11 | -------------------------------------------------------------------------------- /PPSFDD/Listings/Chapter10/listing-10-9.sql: -------------------------------------------------------------------------------- 1 | CREATE TABLE [dbo].PSAppConfig 2 | ( 3 | [Project] varchar(50), 4 | [Name] varchar(100), 5 | [Value] varchar(100), 6 | [CreateDate] datetime default(getdate()), 7 | [UpdateDate] datetime default(getdate()), 8 | Primary Key (Project, Name) 9 | ) 10 | -------------------------------------------------------------------------------- /PPSFDD/Modules/umd_filesearch/umd_filesearch.psm1: -------------------------------------------------------------------------------- 1 | function ufn_search_file ([string]$searchstring,[string] $outfilepath) 2 | { 3 | begin 4 | { 5 | "" > $outfilepath # Clear out file contents 6 | } 7 | process 8 | { 9 | if ($_ -like "*txt*") 10 | { 11 | $_ >> $outfilepath 12 | } 13 | } 14 | } -------------------------------------------------------------------------------- /PPSFDD/Listings/Chapter10/listing-10-2.ps1: -------------------------------------------------------------------------------- 1 | $emailserver='smtp.live.com' 2 | $emailaccount='someacct@msn.com' 3 | $emailfrom='someemail@msn.com' 4 | $emailpw='somepassword' 5 | $edwteamemail='edwteam@msn.com' 6 | $emailport='587' 7 | $ftpinpath='\\ftp\inbound\' 8 | $ftpoutpath='\\ftp\outbound\' 9 | $edwserver='(local)' 10 | -------------------------------------------------------------------------------- /PPSFDD/Listings/Chapter08/listing-8-7.ps1: -------------------------------------------------------------------------------- 1 | function Invoke-UdfMyFunction ([string]$parm1, [int]$parm2, $parm3 ) 2 | { 3 | 4 | $PSBoundParameters 5 | 6 | # Do some work... 7 | } 8 | 9 | Invoke-UdfMyFunction "test" 1 "something" 10 | 11 | # Second call - passing $null 12 | # Invoke-UdfMyFunctionWithlogging $null $null $null 13 | -------------------------------------------------------------------------------- /PPSFDD/Listings/Chapter11/listing-11-5.sql: -------------------------------------------------------------------------------- 1 | Create table dbo.Orders 2 | ( 3 | Order_ID integer primary key, 4 | Employee_ID integer, 5 | Order_Date datetime, 6 | Ship_City varchar(150), 7 | Ship_State varchar(100), 8 | Status_ID integer, 9 | Customer_ID integer, 10 | Sales_Tax_Rate decimal(8,2) 11 | ) 12 | -------------------------------------------------------------------------------- /PPSFDD/Modules/umd_appconfig/umd_appconfig.psm1: -------------------------------------------------------------------------------- 1 | $configfile = Join-Path -Path $PSScriptRoot -ChildPath "psappconfig.txt" 2 | $configdata = Get-Content -Path $configfile | ConvertFrom-StringData 3 | 4 | function Get-UdfConfiguation ([string] $configkey) 5 | { 6 | Return $configdata.$configkey 7 | } 8 | 9 | # Get-UdfConfiguation "EDWServer" -------------------------------------------------------------------------------- /PPSFDD/Listings/Chapter13/listing-13-3.ps1: -------------------------------------------------------------------------------- 1 | workflow simplebroken ([string] $myparm) 2 | { 3 | Write-Host "Parameter is $myparm" 4 | 5 | $object = New-Object PSObject 6 | 7 | $object | Add-Member -MemberType NoteProperty -Name MyProperty -Value 'something' 8 | 9 | $object.MyProperty 10 | } 11 | 12 | simplebroken 'test' 13 | -------------------------------------------------------------------------------- /PPSFDD/Listings/Chapter05/Simple_NoCmdletBinding.ps1: -------------------------------------------------------------------------------- 1 | function Write-UdfMessages 2 | { 3 | 4 | Write-Host "This is a regular message." 5 | Write-Verbose "This is a verbose message." 6 | Write-Debug "This is a debug message." 7 | 8 | } 9 | 10 | Write-UdfMessages 11 | Write-UdfMessages -Verbose 12 | Write-UdfMessages -Debug 13 | -------------------------------------------------------------------------------- /PPSFDD/Listings/Chapter10/listing-10-6.csv: -------------------------------------------------------------------------------- 1 | project,name,value 2 | general,edwserver,(local) 3 | general,emailserver,smtp.live.com 4 | general,ftppath,\\ftpserver\ftp\ 5 | edw,teamemail,edwteamdist 6 | edw,stagingdb,staging 7 | finance,ftppath,\\financeftpserver\ftp\ 8 | finance,dbserver,financesqlsvr 9 | finance,outfolder,\\somepath\outdata\ 10 | -------------------------------------------------------------------------------- /PPSFDD/Listings/Chapter13/listing-13-4.ps1: -------------------------------------------------------------------------------- 1 | function simplefunction ([string] $myparm) 2 | { 3 | Write-Host "Parameter is $myparm" 4 | 5 | $object = New-Object PSObject 6 | 7 | $object | Add-Member -MemberType NoteProperty -Name MyProperty -Value 'something' 8 | 9 | $object.MyProperty 10 | 11 | } 12 | 13 | simplefunction 'test' 14 | -------------------------------------------------------------------------------- /PPSFDD/Modules/umd_Simple/scr_test.ps1: -------------------------------------------------------------------------------- 1 | Remove-Module umd_Simple 2 | $test = New-object PSObject 3 | 4 | $test = Import-Module umd_Simple -AsCustomObject 5 | 6 | $test.myvar 7 | 8 | $test.myvar = "Swell" 9 | 10 | $newtest = New-object PSObject 11 | 12 | $newtest = Import-Module umd_Simple -AsCustomObject 13 | 14 | 15 | $newtest.myvar 16 | 17 | 18 | -------------------------------------------------------------------------------- /PPSFDD/Listings/Chapter03/scr_openfiledlg.ps1: -------------------------------------------------------------------------------- 1 | [System.Reflection.Assembly]::LoadWithPartialName("System.windows.forms") | Out-Null 2 | 3 | $OpenFileDialog = New-Object System.Windows.Forms.OpenFileDialog 4 | $OpenFileDialog.initialDirectory = $args[0] 5 | $OpenFileDialog.filter = $args[1] 6 | $OpenFileDialog.ShowDialog() | Out-Null 7 | $OpenFileDialog.filename 8 | -------------------------------------------------------------------------------- /PPSFDD/Listings/Chapter13/listing-13-1.ps1: -------------------------------------------------------------------------------- 1 | $password = Get-Content ($HOMEDRIVE + $env:HOMEPATH + "\Documents\credential.txt" ) | ` 2 | Convertto-Securestring -AsPlainText –Force 3 | 4 | $credential = New-Object System.Management.Automation.PSCredential ("someuser", $password ) 5 | 6 | Invoke-Command -ScriptBlock { Get-Culture } -Credential $credential 7 | -------------------------------------------------------------------------------- /PPSFDD/Listings/Chapter05/listing-5-8.ps1: -------------------------------------------------------------------------------- 1 | function Invoke-UdfValidateStateCode ([string] $statecode) 2 | { 3 | $result = $false 4 | 5 | foreach ($states in $global:statelistglobal) 6 | { 7 | if ($states.StateProvinceCode -eq $statecode) 8 | { 9 | $result = $true } 10 | } 11 | 12 | Return $result 13 | } 14 | -------------------------------------------------------------------------------- /PPSFDD/Listings/Chapter10/listing-10-14.ps1: -------------------------------------------------------------------------------- 1 | $configfile = Join-Path -Path $PSScriptRoot -ChildPath "psappconfig.txt" 2 | $configdata = Get-Content -Path $configfile | ConvertFrom-StringData 3 | 4 | function Get-UdfConfiguation ([string] $configkey) 5 | { 6 | Return $configdata.$configkey 7 | } 8 | 9 | # Example call... 10 | # Get-UdfConfiguation 'emailserver' -------------------------------------------------------------------------------- /PPSFDD/Listings/Chapter13/listing-13-7.ps1: -------------------------------------------------------------------------------- 1 | Import-Module umd_northwind_etl -Force 2 | 3 | Clear-Host 4 | 5 | workflow Invoke-UdwNorthwindETL 6 | { 7 | 8 | parallel 9 | 10 | { 11 | 12 | Invoke-UdfStateSalesTaxLoad 13 | 14 | Invoke-UdfOrderLoad 15 | 16 | Invoke-udfCustomerLoad 17 | 18 | } 19 | 20 | } 21 | 22 | Invoke-UdwNorthwindETL 23 | -------------------------------------------------------------------------------- /PPSFDD/Listings/Chapter06/listing-6-1.ps1: -------------------------------------------------------------------------------- 1 | Import-Module umd_ModuleParms -Force 2 | 3 | Invoke-UdfAddNumber 1 2 # Returns 3 4 | 5 | Invoke-UdfSubtractNumber 5 1 # Returns 4 6 | 7 | Invoke-UdfMultiplyNumber 5 6 # Generates an error because the function is not loaded. 8 | 9 | Get-Module umd_ModuleParms # Confirms that the new function is not loaded. 10 | -------------------------------------------------------------------------------- /PPSFDD/Listings/Chapter04/listing-4-2.ps1: -------------------------------------------------------------------------------- 1 | Try 2 | { 3 | Get-Process -Id 255 -ErrorAction Stop 4 | } 5 | Catch [Microsoft.PowerShell.Commands.ProcessCommandException] 6 | { 7 | write-host "The process id was not found." -ForegroundColor Red 8 | } 9 | Catch 10 | { 11 | "Error: $Error" >> errorlog.txt 12 | } 13 | Finally 14 | { 15 | "Process complete." 16 | } 17 | -------------------------------------------------------------------------------- /PPSFDD/Listings/Chapter13/listing-13-13.ps1: -------------------------------------------------------------------------------- 1 | $filepath = $env:HOMEDRIVE + $env:HOMEPATH + "\Documents\" 2 | 3 | function New-UdfFile ([string]$fullfilepath) 4 | { 5 | for ($i=1; $i -le 30; $i++) 6 | { 7 | Get-ChildItem | Out-File ($fullfilepath) -Append 8 | } 9 | } 10 | 11 | New-UdfFile ($filepath + "logfile1.txt") 12 | New-UdfFile ($filepath + "logfile2.txt") 13 | -------------------------------------------------------------------------------- /PPSFDD/Listings/Chapter06/listing-6-2.ps1: -------------------------------------------------------------------------------- 1 | Import-Module umd_ModuleParms –Force -ArgumentList $true # Displays message new function loaded. 2 | 3 | Invoke-UdfAddNumber 1 2 # Returns 3 4 | 5 | Invoke-UdfSubtractNumber 5 1 # Returns 4 6 | 7 | Invoke-UdfMultiplyNumber 5 6 # Returns 30 8 | 9 | Get-Module umd_ModuleParms # Confirms that the new function is loaded.. 10 | -------------------------------------------------------------------------------- /PPSFDD/Listings/Chapter13/listing-13-6.ps1: -------------------------------------------------------------------------------- 1 | workflow paralleltest { 2 | 3 | parallel 4 | { 5 | 6 | for($i=1; $i -le 10000; $i++){ "a" } 7 | 8 | for($i=1; $i -le 10000; $i++){ "b" } 9 | 10 | for($i=1; $i -le 10000; $i++){ "c" } 11 | 12 | for($i=1; $i -le 10000; $i++){ "d" } 13 | 14 | for($i=1; $i -le 10000; $i++){ "e" } 15 | 16 | } 17 | } 18 | 19 | paralleltest 20 | -------------------------------------------------------------------------------- /PPSFDD/Listings/Chapter04/listing-4-4.ps1: -------------------------------------------------------------------------------- 1 | # Listing 4-4. Workaround to replace a trap 2 | [boolean] $stopscript = $false 3 | 4 | trap { "Error Occurred: $Error."; If ($stopscript -eq $true) {break} } 5 | Get-Process 255 -ErrorAction Stop 6 | 7 | "The script continues..." 8 | $stopscript = $true 9 | 10 | Get-Process 255 -ErrorAction Stop 11 | 12 | "This line will NOT execute" 13 | -------------------------------------------------------------------------------- /PPSFDD/Listings/Chapter08/listing-8-10.ps1: -------------------------------------------------------------------------------- 1 | New-EventLog -LogName DataWarehouse -Source ETL 2 | 3 | Limit-EventLog -LogName DataWarehouse -MaximumSize 10MB -RetentionDays 10 4 | 5 | For ($i=1; $i -le 5; $i++) 6 | { 7 | Write-EventLog -LogName DataWarehouse -Source ETL -EventId 9999 -Message ("DW Event written " + (Get-Date)) 8 | } 9 | 10 | Get-EventLog -LogName DataWarehouse 11 | -------------------------------------------------------------------------------- /PPSFDD/Data/script.sql: -------------------------------------------------------------------------------- 1 | USE AdventureWorks 2 | GO 3 | 4 | SELECT [DepartmentID] 5 | ,[Name] 6 | ,[GroupName] 7 | ,[ModifiedDate] 8 | FROM [HumanResources].[Department]; 9 | 10 | SELECT distinct DepartmentID 11 | ,[Name] 12 | FROM [HumanResources].[Department]; 13 | 14 | SELECT DepartmentID, [Name], GroupName, ModifiedDate 15 | FROM [HumanResources].[Department]; 16 | -------------------------------------------------------------------------------- /PPSFDD/Listings/Chapter05/Simple_CmdletBinding.ps1: -------------------------------------------------------------------------------- 1 | 2 | function Write-UdfMessages 3 | { 4 | [CmdletBinding()] 5 | param () 6 | 7 | Write-Host "This is a regular message." 8 | Write-Verbose "This is a verbose message." 9 | Write-Debug "This is a debug message." 10 | 11 | } 12 | 13 | Write-UdfMessages 14 | Write-UdfMessages -Verbose 15 | Write-UdfMessages -Debug 16 | 17 | 18 | -------------------------------------------------------------------------------- /PPSFDD/Listings/Chapter13/listing-13-12.ps1: -------------------------------------------------------------------------------- 1 | Import-Module umd_workflow -Force 2 | 3 | $global:rootfilepath = $env:HOMEDRIVE + $env:HOMEPATH + '\documents\' 4 | 5 | Register-UdfOrderFileCreateEvent $global:rootfilepath "orders.xml" -sourceidentifier 'orders' 6 | 7 | Register-UdfEmployeeFileCreateEvent $global:rootfilepath "Employees.txt" ` 8 | -sourceidentifier 'employees' 9 | -------------------------------------------------------------------------------- /PPSFDD/Listings/Chapter13/listing-13-5.ps1: -------------------------------------------------------------------------------- 1 | workflow simpleinline ([string] $myparm) 2 | { 3 | inlinescript 4 | { 5 | Write-Verbose "Parameter is $Using:myparm" 6 | 7 | $object = New-Object PSObject 8 | 9 | $object | Add-Member -MemberType NoteProperty -Name MyProperty -Value 'something' 10 | 11 | $object.MyProperty 12 | } 13 | } 14 | 15 | simpleinline 'test' –Verbose 16 | -------------------------------------------------------------------------------- /PPSFDD/Modules/umd_ModuleDotSource/ufn_add_numbers.ps1: -------------------------------------------------------------------------------- 1 | # Simple module example 2 | 3 | function ufn_add_numbers([int]$p_int1, [int]$p_int2) 4 | { 5 | Return ($p_int1 + $p_int2) 6 | } 7 | 8 | function ufn_subtract_numbers([int]$p_int1, [int]$p_int2) 9 | { 10 | Return ($p_int1 - $p_int2) 11 | } 12 | 13 | # Example Function Calls... 14 | # 15 | # ufn_add_numbers 1 4 16 | # ufn_subtract_numbers 4 1 -------------------------------------------------------------------------------- /PPSFDD/Listings/Chapter02/listing-2-10.ps1: -------------------------------------------------------------------------------- 1 | $MsgBox = {param([string] $message, [string] $title, [string] $type) $OFS=','; [System.Windows.Forms.MessageBox]::Show($message , $title, $type) } 2 | 3 | Invoke-Command $MsgBox -ArgumentList "First Message", "Title", "1" 4 | 5 | Invoke-Command $MsgBox -ArgumentList "Second Message", "Title", "1" 6 | 7 | Invoke-Command $MsgBox -ArgumentList "Third Message", "Title", "1" 8 | -------------------------------------------------------------------------------- /PPSFDD/Modules/umd_ModuleDotSource/ufn_subtract_numbers.ps1: -------------------------------------------------------------------------------- 1 | # Simple module example 2 | 3 | function ufn_add_numbers([int]$p_int1, [int]$p_int2) 4 | { 5 | Return ($p_int1 + $p_int2) 6 | } 7 | 8 | function ufn_subtract_numbers([int]$p_int1, [int]$p_int2) 9 | { 10 | Return ($p_int1 - $p_int2) 11 | } 12 | 13 | # Example Function Calls... 14 | # 15 | # ufn_add_numbers 1 4 16 | # ufn_subtract_numbers 4 1 -------------------------------------------------------------------------------- /PPSFDD/Listings/Chapter02/listing-2-7.ps1: -------------------------------------------------------------------------------- 1 | $datetime = Get-Date 2 | 3 | $answer = Read-Host "Enter t for time, d for date or b for both" 4 | 5 | if ($answer -eq 't') { 6 | Write-Host "The time is " $datetime.ToShortTimeString() 7 | } 8 | elseif ($answer -eq "d") { 9 | Write-Host "The date is " $datetime.ToShortDateString() 10 | } 11 | else { 12 | Write-Host "The date and time is $datetime" 13 | } 14 | -------------------------------------------------------------------------------- /PPSFDD/Listings/Chapter08/listing-8-9.ps1: -------------------------------------------------------------------------------- 1 | $DebugPreference = "SilentlyContinue" 2 | 3 | function Show-UdfMyDebugMessage { 4 | [CmdletBinding()] 5 | param () 6 | 7 | Write-Debug "Debug message" 8 | 9 | $DebugPreference 10 | 11 | Write-Debug "2nd Debug message" 12 | 13 | } 14 | 15 | # Call without Debug switch 16 | Show-UdfMyDebugMessage 17 | 18 | # Call with Debug switch 19 | Show-UdfMyDebugMessage -Debug 20 | -------------------------------------------------------------------------------- /PPSFDD/Listings/Chapter07/listing-7-5.sql: -------------------------------------------------------------------------------- 1 | Use AdventureWorks 2 | go 3 | 4 | Declare @JobTitle [nvarchar](50) 5 | Declare @HireDate [date] 6 | Declare @VacationHours [smallint] 7 | 8 | exec [HumanResources].[uspUpdateEmployeePersonalInfoPS] 1, 295847284, '1963-01-01', 'M', 'M', @JobTitle Output, @HireDate Output, @VacationHours Output 9 | 10 | print @JobTitle 11 | print @HireDate 12 | print @VacationHours 13 | -------------------------------------------------------------------------------- /PPSFDD/Listings/Chapter03/scr_openfiledlg_with_parms.ps1: -------------------------------------------------------------------------------- 1 | Param( 2 | [string]$initdir, 3 | [string]$filter 4 | ) 5 | 6 | [System.Reflection.Assembly]::LoadWithPartialName("System.windows.forms") | Out-Null 7 | 8 | $OpenFileDialog = New-Object System.Windows.Forms.OpenFileDialog 9 | $OpenFileDialog.initialDirectory = $initdir 10 | $OpenFileDialog.filter = $filter 11 | $OpenFileDialog.ShowDialog() | Out-Null 12 | $OpenFileDialog.filename 13 | -------------------------------------------------------------------------------- /PPSFDD/Listings/Chapter02/listing-2-8.ps1: -------------------------------------------------------------------------------- 1 | $datetime = Get-Date 2 | $answer = "x" 3 | 4 | while ($answer -ne "e") 5 | { 6 | $answer = Read-Host "Enter d for date, t for time or e to exit" 7 | if ($answer -eq "t") 8 | { 9 | write-host "The time is " $datetime.ToShortTimeString() 10 | } 11 | elseif ($answer -eq "d") 12 | { 13 | write-host "The date is " $datetime.ToShortDateString() 14 | } 15 | 16 | } 17 | -------------------------------------------------------------------------------- /PPSFDD/Listings/Chapter05/listing-5-10.ps1: -------------------------------------------------------------------------------- 1 | $global:statelistglobal = Get-udfStatesFromDatabase # To load the global statelist uses Invoke-UdfValidateStateCode 2 | 3 | $rootfolder = $env:HOMEDRIVE + $env:HOMEPATH + "\Documents\" 4 | 5 | Invoke-UdfTestValidation $rootfolder 'MA' # Passes - good path and state code 6 | 7 | Invoke-UdfTestValidation $rootfolder 'XX' # Fails - Invalid state code 8 | 9 | Invoke-UdfTestValidation "c:\xyzdir" 'RI' # Fails - Invalid path -------------------------------------------------------------------------------- /PPSFDD/Listings/Chapter08/listing-8-11.ps1: -------------------------------------------------------------------------------- 1 | function Invoke-UdfSomething 2 | { 3 | [CmdletBinding()] 4 | param ( 5 | [string] $someparm1, 6 | [string] $someparm2 7 | ) 8 | 9 | Write-Host "`$someparm1 is $someparm1" 10 | Write-Host "`$someparm2 is $someparm2" 11 | } 12 | 13 | $PSDefaultParameterValues=@{ 14 | "Invoke-Udf*:someparm1"="my paramater value"; 15 | } 16 | 17 | Invoke-UdfSomething 18 | -------------------------------------------------------------------------------- /PPSFDD/Listings/Chapter02/listing-2-9.ps1: -------------------------------------------------------------------------------- 1 | $datetime = Get-Date 2 | $answer = "e" 3 | 4 | Do 5 | { 6 | $answer = Read-Host "Enter d for date, t for time or e to exit" 7 | if ($answer -eq "t") 8 | { 9 | write-host "The time is " $datetime.ToShortTimeString() 10 | } 11 | elseif ($answer -eq "d") 12 | { 13 | write-host "The date is " $datetime.ToShortDateString() 14 | } 15 | 16 | } 17 | until ($answer -eq "e") 18 | -------------------------------------------------------------------------------- /PPSFDD/Listings/Chapter04/listing-4-5.sql: -------------------------------------------------------------------------------- 1 | CREATE TABLE [HumanResources].[CompanyUnit]( 2 | [UnitID] [smallint] NOT NULL, 3 | [UnitName] [dbo].[Name] NOT NULL, 4 | [UnitGroupName] [dbo].[Name] NOT NULL, 5 | [UpdateDate] [datetime] NOT NULL, 6 | CONSTRAINT [PK_DepartmentNew_UnitID] PRIMARY KEY CLUSTERED 7 | ( 8 | [UnitID] ASC 9 | ) ) 10 | Go 11 | 12 | insert into [HumanResources].[CompanyUnit] 13 | select * from [HumanResources].[Department] 14 | go 15 | -------------------------------------------------------------------------------- /PPSFDD/Listings/Chapter10/listing-10-3.ps1: -------------------------------------------------------------------------------- 1 | Import-Module -Name umd_etl_functions 2 | 3 | $Params = @{ 4 | smtpServer = $global:emailserver 5 | from = $global:emailfrom 6 | to = $global:edwteamemail 7 | subject = 'Important Message' 8 | body = 'ETL Job executed' 9 | port = $global:emailport 10 | usecredential = $true 11 | emailaccount = $global:emailaccount 12 | password = $global:emailpw 13 | } 14 | Send-UdfMail @Params 15 | 16 | -------------------------------------------------------------------------------- /PPSFDD/Listings/Chapter07/listing-7-2.sql: -------------------------------------------------------------------------------- 1 | Create PROCEDURE [HumanResources].[uspListEmployeePersonalInfoPS] 2 | @BusinessEntityID [int] 3 | WITH EXECUTE AS CALLER 4 | AS 5 | BEGIN 6 | SET NOCOUNT ON; 7 | 8 | BEGIN TRY 9 | 10 | select * 11 | from [HumanResources].[Employee] 12 | where [BusinessEntityID] = @BusinessEntityID; 13 | 14 | END TRY 15 | BEGIN CATCH 16 | EXECUTE [dbo].[uspLogError]; 17 | END CATCH; 18 | END; 19 | 20 | GO 21 | -------------------------------------------------------------------------------- /PPSFDD/Listings/Chapter10/listing-10-8.ps1: -------------------------------------------------------------------------------- 1 | # Create new machine level environment variables to point to the database configuration table. 2 | [Environment]::SetEnvironmentVariable("psappconfigdbserver", "(local)", "Machine") 3 | 4 | [Environment]::SetEnvironmentVariable("psappconfigdbname","Development", "Machine") 5 | 6 | [Environment]::SetEnvironmentVariable("psappconfigtablename","dbo.PSAppConfig", "Machine") 7 | 8 | Get-Process explorer | Stop-Process # Line to address Windows bug 9 | -------------------------------------------------------------------------------- /PPSFDD/Listings/Chapter03/listing-3-12.ps1: -------------------------------------------------------------------------------- 1 | $conn = new-Object System.Data.SqlClient.SqlConnection("Server=(local);DataBase=AdventureWorks;Integrated Security=SSPI") 2 | $conn.Open() | out-null 3 | 4 | $cmd = new-Object System.Data.SqlClient.SqlCommand("select top 10 FirstName, LastName from Person.Person", $conn) 5 | 6 | $rdr = $cmd.ExecuteReader() 7 | 8 | While($rdr.Read()){ 9 | Write-Host "Name: " $rdr['FirstName'] $rdr['LastName'] 10 | } 11 | 12 | $conn.Close() 13 | $rdr.Close() 14 | 15 | -------------------------------------------------------------------------------- /PPSFDD/Modules/umd_Simple/umd_Simple_withexport.psm1: -------------------------------------------------------------------------------- 1 | # Simple module example 2 | 3 | $somevar = 'Default Value' 4 | 5 | function ufn_add_numbers([int]$p_int1, [int]$p_int2) 6 | { 7 | Return ($p_int1 + $p_int2) 8 | } 9 | 10 | function ufn_subtract_numbers([int]$p_int1, [int]$p_int2) 11 | { 12 | Return ($p_int1 - $p_int2) 13 | } 14 | 15 | Export-ModuleMembers ufn_add_numbers, somevar 16 | 17 | # Example Function Calls... 18 | # 19 | # ufn_add_numbers 1 4 20 | # ufn_subtract_numbers 4 1 -------------------------------------------------------------------------------- /PPSFDD/Listings/Chapter08/listing-8-2.ps1: -------------------------------------------------------------------------------- 1 | function Invoke-UdfProcessPipelineEndBlock() { 2 | Begin { 3 | # Executes before the pipeline is loaded, i.e. $input is empty. 4 | "Begin block pipeline..." 5 | $Input 6 | } 7 | 8 | # No process block. 9 | 10 | End { 11 | # Since the Process block 12 | "End block pipeline..." 13 | $Input 14 | } 15 | } 16 | 17 | # Pipe data into the function Invoke-UdfProcessPipeline 18 | ("A", "B", "C") | Invoke-UdfProcessPipelineEndBlock 19 | -------------------------------------------------------------------------------- /PPSFDD/Listings/Chapter08/listing-8-5.ps1: -------------------------------------------------------------------------------- 1 | function Invoke-UdfMyFunctionWithlogging ([string]$parm1, [int]$parm2, $parm3 ) 2 | { 3 | 4 | $logfilepath = $MyInvocation.PSScriptRoot + '\logfile.txt' 5 | 6 | $logline = "function called: " + $MyInvocation.InvocationName + " at " ` 7 | + (Get-Date -format g) + " with parms: " + $MyInvocation.BoundParameters.Keys 8 | 9 | $logline >> $logfilepath 10 | 11 | $logline 12 | 13 | } 14 | 15 | Invoke-UdfMyFunctionWithlogging "test" 1 "something" 16 | -------------------------------------------------------------------------------- /PPSFDD/Listings/Chapter03/listing-3-7.ps1: -------------------------------------------------------------------------------- 1 | function Invoke-UdfPipeProcess ( [Parameter(ValueFromPipeline=$True)]$mypipe = "default") 2 | 3 | { 4 | 5 | begin { 6 | Write-Host "Getting ready to process the pipe. `r`n" 7 | } 8 | 9 | process { Write-Host "Processing : $mypipe" 10 | } 11 | 12 | end {Write-Host "`r`nWhew! That was a lot of work." } 13 | 14 | } 15 | 16 | # Code to call the function… 17 | Set-Location c:\ 18 | Get-ChildItem | Invoke-UdfPipeProcess 19 | -------------------------------------------------------------------------------- /PPSFDD/Modules/umd_Simple_withexport/umd_Simple_withexport.psm1: -------------------------------------------------------------------------------- 1 | # Simple module example 2 | 3 | $somevar = 'Default Value' 4 | 5 | function ufn_add_numbers([int]$p_int1, [int]$p_int2) 6 | { 7 | Return ($p_int1 + $p_int2) 8 | } 9 | 10 | function ufn_subtract_numbers([int]$p_int1, [int]$p_int2) 11 | { 12 | Return ($p_int1 - $p_int2) 13 | } 14 | 15 | Export-ModuleMember -function ufn_add_numbers -variable somevar 16 | 17 | # Example Function Calls... 18 | # 19 | # ufn_add_numbers 1 4 20 | # ufn_subtract_numbers 4 1 -------------------------------------------------------------------------------- /PPSFDD/Listings/Chapter11/listing-11-6.sql: -------------------------------------------------------------------------------- 1 | CREATE TABLE [dbo].[Customers]( 2 | [Customer_ID] [int] NOT NULL, 3 | [Company_Name] [varchar](50) NULL, 4 | [First_Name] [varchar](50) NULL, 5 | [Last_Name] [varchar](50) NULL, 6 | [Title] [varchar](50) NULL, 7 | [City] [varchar](50) NULL, 8 | [State] [varchar](50) NULL, 9 | [Zip] [varchar](15) NULL, 10 | [Country] [varchar](50) NULL, 11 | [State_Name] varchar(255) null, 12 | [State_Region] varchar(255) null 13 | PRIMARY KEY CLUSTERED 14 | ( 15 | [Customer_ID] ASC 16 | ) ) 17 | -------------------------------------------------------------------------------- /PPSFDD/Listings/Chapter13/listing-13-8.ps1: -------------------------------------------------------------------------------- 1 | Import-Module umd_northwind_etl -Force 2 | 3 | workflow Invoke-UdwNorthwindETL 4 | { 5 | 6 | parallel 7 | 8 | { 9 | 10 | workflow Invoke-UdwStateSalesTaxLoad 11 | { 12 | Invoke-UdfStateSalesTaxLoad 13 | } 14 | Invoke-UdwStateSalesTaxLoad -PSComputerName remotepc1 15 | 16 | workflow Invoke-UfwOrderLoad 17 | { 18 | Invoke-UdfOrderLoad 19 | } 20 | Invoke-UfwOrderLoad -PSComputerName remotepc2 21 | } 22 | 23 | } 24 | 25 | Invoke-UdwNorthwindETL 26 | -------------------------------------------------------------------------------- /PPSFDD/Listings/Chapter13/listing-13-11.ps1: -------------------------------------------------------------------------------- 1 | workflow Invoke-UdwWorkflowCommand { 2 | 3 | sequence 4 | { 5 | "1" 6 | "2" 7 | "3" 8 | } 9 | 10 | parallel 11 | { 12 | 13 | for($i=1; $i -le 100; $i++){ "a" } 14 | 15 | for($i=1; $i -le 100; $i++){ "b" } 16 | 17 | for($i=1; $i -le 100; $i++){ "c" } 18 | 19 | } 20 | 21 | $collection = "one","two","three" 22 | 23 | foreach -parallel ($item in $collection) 24 | { 25 | "Length is: " + $item.Length 26 | } 27 | 28 | } 29 | 30 | Invoke-UdwWorkflowCommand 31 | -------------------------------------------------------------------------------- /PPSFDD/Listings/Chapter13/listing-13-14.ps1: -------------------------------------------------------------------------------- 1 | Remove-Module umd_workflow 2 | Import-Module umd_workflow # To get the functions we will use below 3 | 4 | $filepath = $env:HOMEDRIVE + $env:HOMEPATH + "\Documents\" 5 | $filelist = "logcombined.txt", "logcombined2.txt", "logcombined3.txt", "logcombined4.txt" 6 | 7 | Clear-Host # Just to clear the console. 8 | 9 | $starttime = Get-Date 10 | Search-UdwFile -filepath $filepath -filelist $filelist -searchstring "*txt*" 11 | $endtime = get-date 12 | "Execution time: " + ($endtime - $starttime) 13 | -------------------------------------------------------------------------------- /PPSFDD/Listings/Chapter02/listing-2-2.ps1: -------------------------------------------------------------------------------- 1 | Set-Location $env:USERPROFILE 2 | $streamin = new-object System.IO.StreamReader("file1.txt") 3 | $streamout = new-object System.IO.StreamWriter("file2.txt", 'Append') 4 | 5 | [string] $inline = $streamin.ReadLine() 6 | 7 | Do 8 | { 9 | if ($inline.Contains("stuff") ) 10 | { 11 | $inline 12 | $streamout.WriteLine($inline) 13 | } 14 | $inline=$streamin.ReadLine() 15 | } Until ($streamin.EndOfStream) 16 | 17 | $streamout.Close() 18 | $streamin.Close() 19 | 20 | -------------------------------------------------------------------------------- /PPSFDD/Listings/Chapter04/listing-4-7.ps1: -------------------------------------------------------------------------------- 1 | Import-Module “sqlps” -DisableNameChecking 2 | 3 | $outpath = $env:HOMEDRIVE + $env:HOMEPATH + "\Documents\storedprocedures.sql" 4 | 5 | # Let's clear out the output file first. 6 | "" > $outpath 7 | 8 | # Set where you are in SQL Server... 9 | set-location SQLSERVER:\SQL\BryanCafferkyPC\DEFAULT\Databases\Adventureworks\StoredProcedures 10 | 11 | foreach ($Item in Get-ChildItem) 12 | { 13 | $Item.Schema + "_" + $Item.Name 14 | $Item.Script() | Out-File -Filepath $outpath -append 15 | } 16 | -------------------------------------------------------------------------------- /PPSFDD/Listings/Chapter08/listing-8-8.ps1: -------------------------------------------------------------------------------- 1 | function Invoke-UdfPSCmdlet { 2 | [CmdletBinding()] 3 | param ( 4 | ) 5 | 6 | Write-Host "Here is a dump of `$PSCmdLet..." 7 | $PSCmdlet 8 | 9 | Write-Host "Here is a list of the MyInvocaton attributes..." 10 | $PSCmdlet.MyInvocation 11 | 12 | if($PSCmdlet.ShouldContinue('Click Yes to see GridView of methods and properties...', 'Show GridView')) 13 | { 14 | $PSCmdlet | Get-Member | Out-GridView 15 | } 16 | 17 | } 18 | 19 | Invoke-UdfPSCmdlet 20 | -------------------------------------------------------------------------------- /PPSFDD/Listings/Chapter13/listing-13-15.ps1: -------------------------------------------------------------------------------- 1 | Import-Module umd_workflow # To get the functions we will use below 2 | 3 | $filelist1 = "logcombined.txt", "logcombined2.txt" 4 | $filelist2 = "logcombined3.txt", "logcombined4.txt" 5 | 6 | Search-UdfFile -filepath $filepath -filelist $filelist1 -searchstring "*txt*" ` 7 | –PSComputerName remote1 –AsJob –JobName ‘remote1search’ 8 | 9 | Search-UdfFile -filepath $filepath -filelist $filelist2 -searchstring "*txt*" ` 10 | –PSComputerName remote2 –AsJob –JobName ‘remote2search’ 11 | -------------------------------------------------------------------------------- /PPSFDD/Listings/Chapter06/listing-6-3.ps1: -------------------------------------------------------------------------------- 1 | # Example of a Dynamic Module... 2 | 3 | $scrblock = { 4 | function Get_UdfLetters([string]$p_instring) 5 | { 6 | Return ($p_instring -replace '[^A-Z ]','') 7 | } 8 | 9 | function Get_UdfNumbers([string]$p_instring) 10 | { 11 | Return ($p_instring -replace '[^0-9]','') 12 | } 13 | 14 | } 15 | 16 | $mod = new-module -scriptblock $scrblock -AsCustomObject 17 | 18 | $mod | Get-Member 19 | 20 | $mod.Get_UdfLetters("mix of numbers 12499 and letters") 21 | 22 | $mod.Get_UdfNumbers("mix of numbers 12499 and letters") -------------------------------------------------------------------------------- /PPSFDD/Modules/umd_ModuleDotSource/umd_ModuleDotSource.psm1: -------------------------------------------------------------------------------- 1 | <# 2 | 3 | .Author 4 | Bryan Cafferky 5 | .SYNOPSIS 6 | A simple module to demonstrate using dot sourcing to load the functions. 7 | .DESCRIPTION 8 | When this module is imported, the functions are loaded using dot sourcing. 9 | 10 | 11 | 12 | #> 13 | 14 | param ( [switch]$IncludeExtended ) 15 | 16 | . ($PSScriptRoot + "\ufn_add_numbers.ps1") 17 | 18 | . ($PSScriptRoot + "\ufn_subtract_numbers.ps1") 19 | 20 | if ($IncludeExtended) 21 | { 22 | Write-Host "Adding extended modules." 23 | } 24 | 25 | 26 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Apress Source Code 2 | 3 | This repository accompanies [*Pro PowerShell for Database Developers*](http://www.apress.com/9781484205426) by Bryan P. Cafferky (Apress, 2015). 4 | 5 | ![Cover image](9781484205426.jpg) 6 | 7 | Download the files as a zip using the green button, or clone the repository to your machine using Git. 8 | 9 | ## Releases 10 | 11 | Release v1.0 corresponds to the code in the published book, without corrections or updates. 12 | 13 | ## Contributions 14 | 15 | See the file Contributing.md for more information on how you can contribute to this repository. 16 | -------------------------------------------------------------------------------- /PPSFDD/Listings/Chapter07/listing-7-3.ps1: -------------------------------------------------------------------------------- 1 | Import-Module umd_database -Force 2 | 3 | [psobject] $myconnection = New-Object psobject 4 | New-UdfConnection ([ref]$myconnection) 5 | 6 | $myconnection.ConnectionType = 'ADO' 7 | $myconnection.DatabaseType = 'SqlServer' 8 | $myconnection.Server = '(local)' 9 | $myconnection.DatabaseName = 'AdventureWorks' 10 | $myconnection.UseCredential = 'N' 11 | 12 | $myconnection.SetAuthenticationType('Integrated') 13 | $myconnection.BuildConnectionString 14 | $empid = 1 15 | 16 | $myconnection.RunSQL("exec [HumanResources].[uspListEmployeePersonalInfoPS] $empid", $true) 17 | -------------------------------------------------------------------------------- /PPSFDD/Listings/Chapter10/listing-10-12.ps1: -------------------------------------------------------------------------------- 1 | Import-module umd_database 2 | 3 | [psobject] $myconnection = New-Object psobject 4 | New-UdfConnection([ref]$myconnection) 5 | 6 | $myconnection.ConnectionType = 'ADO' 7 | $myconnection.DatabaseType = 'SqlServer' 8 | $myconnection.Server = $global:psappconfig.finance.dbserver 9 | $myconnection.DatabaseName = $global:psappconfig.finance.dbname 10 | $myconnection.UseCredential = 'N' 11 | $myconnection.SetAuthenticationType('Integrated') 12 | $myconnection.BuildConnectionString() 13 | $myconnection.RunSQL("select top 10 * from [Sales].[SalesTerritory]", $true) 14 | -------------------------------------------------------------------------------- /PPSFDD/Listings/Chapter11/listing-11-4.sql: -------------------------------------------------------------------------------- 1 | CREATE TABLE [dbo].[Products]( 2 | [SupplierIDs] [nvarchar](max) NULL, 3 | [ID] [int] NOT NULL, 4 | [ProductCode] [nvarchar](25) NULL, 5 | [ProductName] [nvarchar](50) NULL, 6 | [Description] [nvarchar](max) NULL, 7 | [StandardCost] [money] NULL, 8 | [ListPrice] [money] NOT NULL, 9 | [ReorderLevel] [smallint] NULL, 10 | [TargetLevel] [int] NULL, 11 | [QuantityPerUnit] [nvarchar](50) NULL, 12 | [Discontinued] [varchar](5) NOT NULL, 13 | [MinimumReorderQuantity] [smallint] NULL, 14 | [Category] [nvarchar](50) NULL, 15 | [Attachments] [nvarchar](max) NULL 16 | ) 17 | -------------------------------------------------------------------------------- /PPSFDD/Listings/Chapter05/listing-5-9.ps1: -------------------------------------------------------------------------------- 1 | function Invoke-UdfTestValidation 2 | { 3 | [cmdletBinding()] 4 | param ( 5 | [ parameter(mandatory=$true, HelpMessage="Enter a folder path .")] 6 | [ValidateScript({ Test-Path $_ -PathType Container })] 7 | [string] $folder, 8 | [parameter(mandatory=$true, HelpMessage="Enter a New England state code.")] 9 | [ValidateScript({ Invoke-UdfValidateStateCode $_ })] 10 | [string] $statecode 11 | 12 | ) 13 | write-verbose $statecode 14 | } 15 | 16 | 17 | -------------------------------------------------------------------------------- /PPSFDD/Listings/Chapter06/listing-6-5.ps1: -------------------------------------------------------------------------------- 1 | Import-Module WASP # Use Import-Module starting with PowerShell 3.0 2 | 3 | $url = "http://www.bing.com" 4 | 5 | stop-process -processname iexplore* 6 | 7 | $ie = New-Object -comobject InternetExplorer.Application 8 | $ie.visible = $true 9 | $ie.silent = $true 10 | $ie.Navigate( $url ) 11 | 12 | start-sleep 2 13 | 14 | Select-Window "iexplore" | Set-WindowActive 15 | 16 | $txtArea=$ie.Document.getElementById("sb_form_q") 17 | $txtArea.InnerText="PowerShell WASP Examples" 18 | start-sleep 2 19 | 20 | Select-Window "iexplore" | Set-WindowActive| Send-Keys "{ENTER}" 21 | -------------------------------------------------------------------------------- /PPSFDD/Listings/Chapter05/listing-5-4.ps1: -------------------------------------------------------------------------------- 1 | function Invoke-UdfTestValidationNEState 2 | { 3 | [cmdletBinding()] 4 | param ( 5 | [parameter(mandatory=$true, 6 | HelpMessage="Enter a New England state code .")] 7 | [ValidateSet("ME","NH","VT", "MA", "RI", "CT")] 8 | [string] $newenglandstates 9 | ) 10 | 11 | write-verbose $newenglandstates 12 | } 13 | 14 | Invoke-UdfTestValidationNEState "RI" -Verbose # Passes - RI is in the validation list. 15 | 16 | Invoke-UdfTestValidationNEState "NY" -Verbose # Fails - NY is not in the validation list 17 | -------------------------------------------------------------------------------- /PPSFDD/Listings/Chapter10/listing-10-5.ps1: -------------------------------------------------------------------------------- 1 | # Listing 10-5. Calling Send-UdfMail using global configuration variables 2 | Import-Module –Name umd_etl_functions 3 | 4 | $Params = @{ 5 | smtpServer = $global:psappconfig.emailserver 6 | from = $global:psappconfig.emailfrom 7 | to = $global:psappconfig.edwteamemail 8 | subject = 'Important Message' 9 | body = 'ETL Job executed' 10 | port = $global:psappconfig.emailport 11 | usecredential = $true 12 | emailaccount = $global:psappconfig.emailaccount 13 | password = $global:psappconfig.emailpw 14 | } 15 | 16 | Send-UdfMail @Params 17 | 18 | 19 | -------------------------------------------------------------------------------- /PPSFDD/Listings/Chapter05/listing-5-22.ps1: -------------------------------------------------------------------------------- 1 | function Invoke-UdfDefaultParameterSet 2 | { 3 | [cmdletBinding(DefaultParametersetName="set1")] 4 | param ( 5 | [Parameter(Mandatory = $true, Position = 0, ParameterSetName = "set1")] 6 | [string]$string1, 7 | [Parameter(Mandatory = $true, Position = 0, ParameterSetName = "set2")] 8 | [string]$string2 9 | ) 10 | 11 | Switch ($PScmdlet.ParameterSetName) 12 | { 13 | "set1" { "You called with set1." } 14 | "set2" { "You called with set2." } 15 | } 16 | 17 | } 18 | 19 | Invoke-UdfDefaultParameterSet "test" 20 | -------------------------------------------------------------------------------- /PPSFDD/Modules/umd_Simple/umd_Simple.psm1: -------------------------------------------------------------------------------- 1 | # Simple module example 2 | $somevar = 'Default Value' 3 | 4 | function Invoke-UdfAddNumber([int]$p_int1, [int]$p_int2) 5 | { 6 | Return ($p_int1 + $p_int2) 7 | } 8 | 9 | function Invoke-UdfSubtractNumber([int]$p_int1, [int]$p_int2) 10 | { 11 | Return ($p_int1 - $p_int2) 12 | } 13 | 14 | $mInfo = $MyInvocation.MyCommand.ScriptBlock.Module 15 | 16 | $mInfo.OnRemove = { 17 | Write-Host "Remove Modules" 18 | } 19 | 20 | Export-ModuleMember -Function Invoke-UdfAddNumber -Variable somevar 21 | 22 | # Example Function Calls... 23 | # 24 | # Invoke-UdfAddNumber 1 4 25 | # Invoke-UdfSubtractNumber 4 1 -------------------------------------------------------------------------------- /PPSFDD/Listings/Chapter08/listing-8-3.ps1: -------------------------------------------------------------------------------- 1 | function Invoke-UdfProcessPipelineEndBlockReset() { 2 | Begin { 3 | # Executes before the pipeline is loaded, i.e. $input is empty. 4 | "Begin block pipeline..." 5 | $Input 6 | } 7 | 8 | End { 9 | # Since the Process block 10 | "End block pipeline..." 11 | "Iterate through first time to process..." 12 | $Input | ForEach-Object {$_} 13 | $Input.Reset() 14 | "Show the pipeline has been reset by listing it again..." 15 | $Input 16 | } 17 | } 18 | 19 | # Pipe data into the function Invoke-UdfProcessPipeline 20 | ("A", "B", "C") | Invoke-UdfProcessPipelineEndBlockReset 21 | -------------------------------------------------------------------------------- /PPSFDD/Listings/Chapter10/listing-10-15.ps1: -------------------------------------------------------------------------------- 1 | 2 | Import-Module -Name umd_appconfig # Must call this to load configurations 3 | 4 | Import-Module -Name umd_etl_functions 5 | 6 | $Params = @{ 7 | smtpServer = (Get-UdfConfiguation 'emailserver') 8 | from = (Get-UdfConfiguation 'emailfrom') 9 | to = (Get-UdfConfiguation 'edwteamemail') 10 | subject = 'Important Message' 11 | body = 'ETL Job executed' 12 | port = (Get-UdfConfiguation 'emailport') 13 | usecredential = '' 14 | emailaccount = (Get-UdfConfiguation 'emailaccount') 15 | password = (Get-UdfConfiguation 'emailpw') 16 | } 17 | Send-UdfMail @Params 18 | 19 | 20 | 21 | -------------------------------------------------------------------------------- /PPSFDD/Listings/Chapter10/listing-10-17.ps1: -------------------------------------------------------------------------------- 1 | <# 2 | 3 | .Author 4 | Bryan Cafferky 5 | .SYNOPSIS 6 | A simple module that uses dot sourcing to load the functions. 7 | .DESCRIPTION 8 | When this module is imported, the functions are loaded using dot sourcing. 9 | 10 | #> 11 | 12 | # Get the path to the function files... 13 | $functionpath = $PSScriptRoot + "\function\" 14 | 15 | # Get a list of all the function file names... 16 | $functionlist = Get-ChildItem -Path $functionpath -Name 17 | 18 | # Loop over alll the files and dot source them into memory.. 19 | foreach ($function in $functionlist) 20 | { 21 | . ($functionpath + $function) 22 | } 23 | -------------------------------------------------------------------------------- /PPSFDD/Data/StateSalesTaxRates.csv: -------------------------------------------------------------------------------- 1 | StateCode,SalesTaxRate 2 | AL,0.04 3 | AK,0 4 | AZ,0.06 5 | AR,0.07 6 | CA,0.08 7 | CO,0.03 8 | CT,0.06 9 | DE,0 10 | FL,0.06 11 | GA,0.04 12 | HI,0.04 13 | ID,0.06 14 | IL,0.06 15 | IN,0.07 16 | IA,0.06 17 | KS,0.06 18 | KN,0.06 19 | LA,0.04 20 | ME,0.06 21 | MD,0.06 22 | MA,0.06 23 | MI,0.06 24 | MN,0.07 25 | MS,0.07 26 | MO,0.04 27 | MT,0 28 | NE,0.06 29 | NV,0.07 30 | NH,0 31 | NJ,0.07 32 | NM,0.05 33 | NY,0.04 34 | NC,0.05 35 | ND,0.05 36 | OH,0.06 37 | OK,0.05 38 | OR,0 39 | PA,0.06 40 | RI,0.07 41 | SC,0.06 42 | SD,0.04 43 | TN,0.07 44 | TX,0.06 45 | UT,0.06 46 | VT,0.06 47 | VA,0.05 48 | WA,0.07 49 | WV,0.06 50 | WI,0.05 51 | WY,0.04 52 | DC,0.06 53 | -------------------------------------------------------------------------------- /PPSFDD/Data/create_table_1.sql: -------------------------------------------------------------------------------- 1 | /* 2 | 3 | Author: Bryan Cafferky Date: 2014-03-11 4 | 5 | Purpose: Staging table to hold Core Eligibiity data. 6 | 7 | */ 8 | 9 | If Object_ID('dbo.Table1') is not null 10 | begin 11 | drop table dbo.Table1 12 | Print 'Table dbo.Table1 found and dropped...' 13 | end; 14 | 15 | CREATE TABLE dbo.table1 16 | ( 17 | id integer identity(1,1) not null PRIMARY KEY CLUSTERED, 18 | field1 varchar(50) NULL, 19 | field2 varchar(50) NULL 20 | ) 21 | 22 | 23 | 24 | -------------------------------------------------------------------------------- /PPSFDD/Modules/umd_ModuleParms/umd_ModuleParms.psm1: -------------------------------------------------------------------------------- 1 | <# 2 | 3 | .Author 4 | Bryan Cafferky 5 | .SYNOPSIS 6 | A simple module to demonstrate using dot sourcing to load the functions that includes a parameter. 7 | .DESCRIPTION 8 | When this module is imported, the functions are loaded using dot sourcing. 9 | 10 | #> 11 | 12 | param ( [switch]$IncludeExtended ) 13 | 14 | . ($PSScriptRoot + "\Invoke-UdfAddNumber.ps1") 15 | 16 | . ($PSScriptRoot + "\Invoke-UdfSubtractNumber.ps1") 17 | 18 | if ($IncludeExtended) 19 | { 20 | Write-Host "Adding extended function: $PSScriptRoot\Invoke-UdfMultiplyNumber.ps1" 21 | . ($PSScriptRoot + "\Invoke-UdfMultiplyNumber.ps1") 22 | } 23 | 24 | 25 | -------------------------------------------------------------------------------- /PPSFDD/Modules/umd_application/umd_application.psm1: -------------------------------------------------------------------------------- 1 | <# 2 | 3 | .Author 4 | Bryan Cafferky 5 | .SYNOPSIS 6 | A simple module that uses dot sourcing to load the functions. 7 | .DESCRIPTION 8 | When this module is imported, the functions are loaded using dot sourcing. 9 | 10 | #> 11 | 12 | # Get the path to the function files... 13 | $functionpath = $PSScriptRoot + "\function\" 14 | 15 | # Get a list of all the function file names... 16 | $functionlist = Get-ChildItem -Path $functionpath -Name 17 | 18 | # Loop over alll the files and dot source them into memory.. 19 | foreach ($function in $functionlist) 20 | { 21 | . ($functionpath + $function) 22 | } 23 | 24 | 25 | 26 | -------------------------------------------------------------------------------- /PPSFDD/Listings/Chapter05/listing-5-3.ps1: -------------------------------------------------------------------------------- 1 | function Invoke-UdfTestValidationMoney 2 | { 3 | [cmdletBinding()] 4 | param ( 5 | [parameter(mandatory=$true, 6 | HelpMessage="Enter a number with two decimal places.")] 7 | [ValidateLength(5,15)] 8 | [ValidatePattern("^-?\d*\.\d{2}$")] 9 | [string] $inparm1 10 | ) 11 | 12 | write-verbose $inparm1 13 | } 14 | 15 | Invoke-UdfTestValidationMoney "123.22" -Verbose # Good value. 16 | 17 | Invoke-UdfTestValidationMoney "1.1" –Verbose # Not enough digits after the decimal. 18 | 19 | Invoke-UdfTestValidationMoney "12345678912345.25" -Verbose # String is too long. 20 | -------------------------------------------------------------------------------- /PPSFDD/Listings/Chapter07/listing-7-1.ps1: -------------------------------------------------------------------------------- 1 | Import-Module umd_database -Force 2 | 3 | [psobject] $myssint = New-Object psobject 4 | New-UdfConnection ([ref]$myssint) 5 | 6 | $myssint.ConnectionType = 'ADO' 7 | $myssint.DatabaseType = 'SqlServer' 8 | $myssint.Server = '(local)' 9 | $myssint.DatabaseName = 'AdventureWorks' 10 | $myssint.UseCredential = 'N' 11 | $myssint.SetAuthenticationType('Integrated') 12 | $myssint.AuthenticationType 13 | 14 | $myssint.BuildConnectionString 15 | $myssint.Connectionstring 16 | $myssint.RunSQL("SELECT top 20 * FROM [HumanResources].[EmployeeDepartmentHistory]", $true) 17 | $myssint.ConnectionString 18 | 19 | # To see the object's methods and properties... 20 | $myssint|get-member -------------------------------------------------------------------------------- /PPSFDD/Listings/Chapter03/listing-3-11.ps1: -------------------------------------------------------------------------------- 1 | Import-Module "sqlps" 2 | 3 | $word = New-Object -ComObject Word.Application 4 | $doc = $word.Documents.Add() 5 | 6 | $stores = Invoke-Sqlcmd -Query "select top 10 * from [AdventureWorks].Sales.vStoreWithAddresses;" -QueryTimeout 3 7 | 8 | $outdoc = "" 9 | 10 | foreach ($item in $stores) { 11 | $outdoc = $outdoc + $item.Name + "`r`n" 12 | $outdoc = $outdoc + $item.AddressLine1 + "`r`n" 13 | $outdoc = $outdoc + $item.City + ", " + $item.StateProvinceName + " " + $item.PostalCode + "`r`n" 14 | $outdoc = $outdoc + "`f" # Does a page break 15 | } 16 | 17 | $outtext = $doc.Content.Paragraphs.Add() 18 | $outtext.Range.Text = $outdoc 19 | $word.visible = $true 20 | -------------------------------------------------------------------------------- /PPSFDD/Listings/Chapter03/listing-3-13.ps1: -------------------------------------------------------------------------------- 1 | function Register-UdfFileCreateEvent([string] $source, [string] $filter) 2 | { 3 | try 4 | { 5 | Write-Host "Watching $source for new files..." 6 | 7 | $fsw = New-Object IO.FileSystemWatcher $source, $filter -Property @{IncludeSubdirectories = $false; NotifyFilter = [IO.NotifyFilters]'FileName, LastWrite'} 8 | 9 | Register-ObjectEvent $fsw Created -SourceIdentifier FileCreated -Action { 10 | write-host "Your file has arrived." } 11 | 12 | } 13 | catch 14 | { 15 | "Error registering file create event." 16 | } 17 | } 18 | 19 | $datapath = $env:HOMEDRIVE + $env:HOMEPATH + "\Documents\" 20 | Register-UdfFileCreateEvent $datapath "*.txt" 21 | -------------------------------------------------------------------------------- /contributing.md: -------------------------------------------------------------------------------- 1 | # Contributing to Apress Source Code 2 | 3 | Copyright for Apress source code belongs to the author(s). However, under fair use you are encouraged to fork and contribute minor corrections and updates for the benefit of the author(s) and other readers. 4 | 5 | ## How to Contribute 6 | 7 | 1. Make sure you have a GitHub account. 8 | 2. Fork the repository for the relevant book. 9 | 3. Create a new branch on which to make your change, e.g. 10 | `git checkout -b my_code_contribution` 11 | 4. Commit your change. Include a commit message describing the correction. Please note that if your commit message is not clear, the correction will not be accepted. 12 | 5. Submit a pull request. 13 | 14 | Thank you for your contribution! -------------------------------------------------------------------------------- /PPSFDD/Listings/Chapter08/listing-8-1.ps1: -------------------------------------------------------------------------------- 1 | function Invoke-UdfProcessPipeline() { 2 | Begin { 3 | # Executes once, before the pipeline is loaded, i.e. $input is empty. 4 | "Begin block pipeline..." 5 | $Input 6 | } 7 | 8 | Process { 9 | # Executes after pipeline is loaded, once for each item i.e. enumerates through each item in the collection. 10 | "Process block pipeline..." 11 | $Input 12 | } 13 | 14 | End { 15 | # Executes once after the Process block has finished. Since there is a Process block, $input is emptied. 16 | "End block pipeline..." 17 | $Input 18 | } 19 | } 20 | 21 | # Pipe data into the function Invoke-UdfProcessPipeline 22 | ("A", "B", "C") | Invoke-UdfProcessPipeline 23 | -------------------------------------------------------------------------------- /PPSFDD/Listings/Chapter04/listing-4-12.ps1: -------------------------------------------------------------------------------- 1 | function Register-UdfFileCreateEvent([string] $source, [string] $filter) 2 | { 3 | try 4 | { 5 | Write-Host "Watching $source for new files..." 6 | $filesystemwatcher = New-Object IO.FileSystemWatcher $source, 7 | $filter -Property @{IncludeSubdirectories = $false; NotifyFilter = [IO.NotifyFilters]'FileName, LastWrite'} 8 | Register-ObjectEvent $filesystemwatcher Created -SourceIdentifier FileCreated -Action { 9 | write-host "Your file has arrived. The file name is " $Event.SourceEventArgs.Name "." } 10 | } 11 | catch 12 | { 13 | "Error registering file create event." 14 | } 15 | } 16 | 17 | Register-UdfFileCreateEvent ($env:HOMEDRIVE + $env:HOMEPATH + "\Documents\") "*.txt" 18 | -------------------------------------------------------------------------------- /PPSFDD/Listings/Chapter03/scr_openfiledlg_with_parms_andswitches.ps1: -------------------------------------------------------------------------------- 1 | [CmdletBinding()] 2 | Param( 3 | [Parameter(Mandatory=$True,Position=1)] 4 | [string]$initdir, 5 | 6 | [Parameter(Mandatory=$True,Position=2)] 7 | [string]$filter 8 | ) 9 | "VerbosePreference is $VerbosePreference" 10 | "DebugPreference is $DebugPreference" 11 | 12 | Write-Verbose "The initial directory is: $initdir" 13 | Write-Debug "The filter is: $filter" 14 | 15 | [System.Reflection.Assembly]::LoadWithPartialName("System.windows.forms") | Out-Null 16 | 17 | $OpenFileDialog = New-Object System.Windows.Forms.OpenFileDialog 18 | $OpenFileDialog.initialDirectory = $initdir 19 | $OpenFileDialog.filter = $filter 20 | $OpenFileDialog.ShowDialog() | Out-Null 21 | $OpenFileDialog.filename 22 | -------------------------------------------------------------------------------- /PPSFDD/Listings/Chapter04/listing-4-8.ps1: -------------------------------------------------------------------------------- 1 | clear-host 2 | 3 | Set-Location ($env:HOMEDRIVE + $env:HOMEPATH + "\Documents") 4 | $Error.Clear() 5 | Get-Content "nonfile" -ErrorAction Continue 6 | "Continue: $Error " 7 | 8 | $Error.Clear() 9 | Get-Content "nonfile" -ErrorAction Ignore # Error message is not set. 10 | "Ignore: $Error " 11 | 12 | $Error.Clear() 13 | Get-Content "nonfile" -ErrorAction Inquire 14 | "Inquire: $Error " 15 | 16 | $Error.Clear() 17 | Get-Content "nonfile" -ErrorAction SilentlyContinue 18 | "SilentlyContinue: $Error " 19 | 20 | $Error.Clear() 21 | Get-Content "nonfile" -ErrorAction Stop 22 | "Stop: $Error " 23 | 24 | # Suspend is only available for workflows. 25 | $Error.Clear() 26 | Get-Content "nonfile" -ErrorAction Suspend 27 | "Suspend: $Error " 28 | -------------------------------------------------------------------------------- /PPSFDD/Listings/Chapter05/listing-5-5.ps1: -------------------------------------------------------------------------------- 1 | function Invoke-UdfTestValidationInteger 2 | { 3 | [cmdletBinding()] 4 | param ( 5 | [parameter(mandatory=$true, 6 | HelpMessage="Enter a number between 10 and 999.")] 7 | [ValidateRange(10,999)] 8 | [ValidateSet(11,12,13, 14, 15)] 9 | [int] $inparm1 10 | ) 11 | 12 | write-verbose $inparm1 13 | 14 | } 15 | 16 | Invoke-UdfTestValidationInteger 12 -Verbose # Good value. 17 | 18 | Invoke-UdfTestValidationInteger 17 -Verbose # Rejected - Within the range but not in the set. 19 | 20 | Invoke-UdfTestValidationInteger 9999 -Verbose # Value too large. 21 | 22 | Invoke-UdfTestValidationInteger 11.25 -Verbose # Accepts the value but truncates it. 23 | -------------------------------------------------------------------------------- /PPSFDD/Listings/Chapter05/listing-5-11.ps1: -------------------------------------------------------------------------------- 1 | function Invoke-UdfTestDefaultParameters 2 | { 3 | [cmdletBinding()] 4 | param ( 5 | [string] $p_string = 'DefaultString', 6 | [int] $p_int = 99, 7 | [decimal] $p_dec = 999.99, 8 | [datetime] $p_date = (Get-Date), 9 | [bool] $p_bool = $True, 10 | [array] $p_array = @(1,2,3), 11 | [hashtable] $p_hash = @{'US' = 'United States'; 'UK' = 'United Kingdom'} 12 | ) 13 | "String is : $p_string" 14 | "Int is: $p_int" 15 | "Decimal is: $p_dec" 16 | "DateTime is $p_date" 17 | "Boolean is: $p_bool" 18 | "Array is: $p_array" 19 | "Hashtable is: " 20 | $p_hash 21 | 22 | } 23 | # Let’s call the function with the statement below. 24 | Invoke-UdfTestDefaultParameters 25 | -------------------------------------------------------------------------------- /PPSFDD/Listings/Chapter05/listing-5-14.ps1: -------------------------------------------------------------------------------- 1 | function Invoke-UdfTestMandatoryParameter 2 | { 3 | [cmdletBinding()] 4 | param ( 5 | [Parameter(Mandatory = $true)] 6 | [string] $p_string, 7 | [Parameter(Mandatory = $true)] 8 | [int] $p_int, 9 | [Parameter(Mandatory = $true)] 10 | [bool] $p_bool, 11 | [Parameter(Mandatory = $true)] 12 | [array] $p_array, 13 | [Parameter(Mandatory = $true)] 14 | [hashtable] $p_hash 15 | ) 16 | "String is : $p_string" 17 | "Int is: $p_int" 18 | "Boolean is: $p_bool" 19 | "Array is: $p_array" 20 | Write-Host "Hashtable is: " 21 | $p_hash 22 | } 23 | 24 | Invoke-UdfTestMandatoryParameter -p_string '' 25 | 26 | Invoke-UdfTestMandatoryParameter -p_string $null 27 | -------------------------------------------------------------------------------- /PPSFDD/Listings/Chapter05/listing-5-21.ps1: -------------------------------------------------------------------------------- 1 | function Invoke-UdfMuliParameterSet 2 | { 3 | [cmdletBinding()] 4 | param ( 5 | [Parameter(Mandatory = $true, Position = 0, ParameterSetName = "set1")] 6 | [int]$int1, 7 | [Parameter(Mandatory = $true, Position = 0, ParameterSetName = "set2")] 8 | [string]$string2, 9 | [Parameter(Mandatory = $true, Position = 1, ParameterSetName = "set2")] 10 | [Parameter(ParameterSetName = "set1")] 11 | [string]$string3 12 | ) 13 | 14 | Switch ($PScmdlet.ParameterSetName) 15 | { 16 | "set1" { "You called with set1." } 17 | "set2" { "You called with set2." } 18 | } 19 | "You Always pass '$string3' which has a value of $string3." 20 | } 21 | 22 | Invoke-UdfMuliParameterSet "one" "two" 23 | -------------------------------------------------------------------------------- /PPSFDD/Listings/Chapter07/listing-7-7.ps1: -------------------------------------------------------------------------------- 1 | Import-Module umd_database 2 | 3 | $parmset = @() # Create a collection object. 4 | 5 | # Add the parameters we need to use... 6 | $parmset += (Add-UdfParameter "@BusinessEntityID" "Input" "1" "int32" 0) 7 | $parmset += (Add-UdfParameter "@NationalIDNumber" "Input" "295847284" "string" 15) 8 | $parmset += (Add-UdfParameter "@BirthDate" "Input" "1964-02-02" "date" 0) 9 | $parmset += (Add-UdfParameter "@MaritalStatus" "Input" "S" "string" 1) 10 | $parmset += (Add-UdfParameter "@Gender" "Input" "M" "string" 1) 11 | $parmset += (Add-UdfParameter "@JobTitle" "Output" "" "string" 50) 12 | $parmset += (Add-UdfParameter "@HireDate" "Output" "" "date" 0) 13 | $parmset += (Add-UdfParameter "@VacationHours" "Output" "" "int16" 0) 14 | 15 | $parmset | Out-GridView # Verify the parameters are correctly defined. 16 | -------------------------------------------------------------------------------- /PPSFDD/Listings/Chapter03/listing-3-1.ps1: -------------------------------------------------------------------------------- 1 | function Invoke-UdfShownOpenFileDialog { 2 | [CmdletBinding()] 3 | Param( 4 | [Parameter(Mandatory=$True,Position=0)] 5 | [string]$initdir, 6 | 7 | [Parameter(Mandatory=$True,Position=1)] 8 | [string]$filter, 9 | 10 | [switch]$multifile 11 | ) 12 | 13 | [System.Reflection.Assembly]::LoadWithPartialName("System.windows.forms") | Out-Null 14 | 15 | $OpenFileDialog = New-Object System.Windows.Forms.OpenFileDialog 16 | $OpenFileDialog.initialDirectory = $initdir 17 | $OpenFileDialog.filter = $filter 18 | 19 | If ($multifile) 20 | { 21 | $OpenFileDialog.Multiselect = $true 22 | } 23 | 24 | $OpenFileDialog.ShowDialog() | Out-Null 25 | $OpenFileDialog.filename 26 | } 27 | 28 | # Example calling the function… 29 | Invoke-UdfShownOpenFileDialog "C:\" "All files (*.*)| *.*" -multifile 30 | -------------------------------------------------------------------------------- /PPSFDD/Listings/Chapter06/listing-6-4.ps1: -------------------------------------------------------------------------------- 1 | $option = Read-Host "Enter 'A' to Allow underscore or 'D' to disallow the underscore " 2 | 3 | if ($option -ne 'A') { 4 | $scrblock = { 5 | function Get_UdfLetters([string]$p_instring) 6 | { 7 | Return ($p_instring -replace '[^A-Z ]','') 8 | } 9 | function Get_UdfNumbers([string]$p_instring) 10 | { 11 | Return ($p_instring -replace '[^0-9]','') 12 | } 13 | 14 | } 15 | } 16 | else 17 | { 18 | $scrblock = 19 | { 20 | function Get_UdfLetters([string]$p_instring) 21 | { 22 | Return ($p_instring -replace '[^A-Z _]','') 23 | } 24 | 25 | function Get_UdfNumbers([string]$p_instring) 26 | { 27 | Return ($p_instring -replace '[^0-9_]','') 28 | } 29 | } 30 | } 31 | 32 | $mod = new-module -scriptblock $scrblock -AsCustomObject 33 | 34 | $mod.Get_UdfLetters("mix of numbers-_ 12499 and_ letters") 35 | 36 | $mod.Get_UdfNumbers("mix of numbers-_ 12499 and_ letters") 37 | -------------------------------------------------------------------------------- /PPSFDD/Listings/Chapter04/listing-4-6.ps1: -------------------------------------------------------------------------------- 1 | $sourcepath = $env:HOMEDRIVE + $env:HOMEPATH + "\Documents\" 2 | 3 | # Let's trap any errors... 4 | trap { "Error Occurred: $Error." >> ($sourcepath + "errorlog.txt") } 5 | 6 | $file = Get-Content ($sourcepath + "script.sql") -ErrorAction Stop 7 | 8 | $file = $file.replace('[HumanResources].[Department]', '[HumanResources].[CompanyUnit]'); 9 | 10 | # Load the column Mappings... 11 | $incolumnemapping = Import-CSV ($sourcepath + "columnmapping.csv") 12 | 13 | foreach ($item in $incolumnemapping) { $file = $file.replace(($item.SourceColumn), ($item.TargetColumn) ) } 14 | 15 | Try 16 | { 17 | $file > ($sourcepath + "script_revised.sql") 18 | "File script.sql has been processed." 19 | } 20 | Catch 21 | { 22 | "Error Writing file Occurred: $Error." >> ($sourcepath + "errorlog.txt") 23 | } 24 | Finally 25 | { 26 | "Mapping process executed on " + (Get-Date) + "." >> ($sourcepath + "executionlog.txt") 27 | } 28 | -------------------------------------------------------------------------------- /PPSFDD/Listings/Chapter05/listing-5-7.ps1: -------------------------------------------------------------------------------- 1 | # Load the state code array 2 | function Get-udfStatesFromDatabase 3 | { 4 | [cmdletBinding()] 5 | param ( 6 | ) 7 | 8 | $conn = new-object System.Data.SqlClient.SqlConnection("Data Source=(local);Integrated Security=SSPI;Initial Catalog=AdventureWorks"); 9 | $conn.Open() 10 | 11 | $command = $conn.CreateCommand() 12 | 13 | $command.CommandText = "SELECT cast(StateProvinceCode as varchar(2)) as StateProvinceCode FROM [AdventureWorks].[Person].[StateProvince] where CountryRegionCode = 'US';" 14 | 15 | $SqlAdapter = New-Object System.Data.SqlClient.SqlDataAdapter 16 | $SqlAdapter.SelectCommand = $command 17 | $DataSet = New-Object System.Data.DataSet 18 | $SqlAdapter.Fill($DataSet) 19 | 20 | Return $DataSet.Tables[0] 21 | 22 | $conn.Close() 23 | } 24 | 25 | $global:statelistglobal = Get-udfStatesFromDatabase # Loads the state codes into variable $global:statelistglobal 26 | $global:statelistglobal 27 | -------------------------------------------------------------------------------- /PPSFDD/Listings/Chapter10/listing-10-7.ps1: -------------------------------------------------------------------------------- 1 | function Set-UdfConfiguration { 2 | [CmdletBinding()] 3 | param ( 4 | [string] $configpath 5 | ) 6 | [psobject] $config = New-Object psobject 7 | 8 | $projects = Import-CSV -Path $configpath | Select-Object -Property Project -Unique 9 | $configvals = Import-CSV -Path $configpath 10 | 11 | foreach ($project in $projects) 12 | { 13 | $configlist = @{} 14 | 15 | foreach ($item in $configvals) 16 | { 17 | if ($item.project -eq $project.project ) { $configlist.Add($item.name, $item.value) } 18 | } 19 | 20 | # Add the noteproperty with the configuration hashtable as the value. 21 | $config | Add-Member -MemberType NoteProperty -Name $project.project -Value $configlist 22 | } 23 | 24 | Return $config 25 | 26 | } 27 | 28 | $global:psappconfig = Set-UdfConfiguration ($env:psappconfigpath) -------------------------------------------------------------------------------- /PPSFDD/Listings/Chapter10/listing-10-10.sql: -------------------------------------------------------------------------------- 1 | insert into [dbo].PSAppConfig (Project, [Name], [Value]) 2 | Values ('general','edwserver','(local)'); 3 | 4 | insert into [dbo].PSAppConfig (Project, [Name], [Value]) 5 | Values ('general','emailserver','smtp.live.com'); 6 | 7 | insert into [dbo].PSAppConfig (Project, [Name], [Value]) 8 | Values ('general','ftppath','\\ftpserver\ftp\'); 9 | 10 | insert into [dbo].PSAppConfig (Project, [Name], [Value]) 11 | Values ('edw','teamemail','edwteamdist'); 12 | 13 | insert into [dbo].PSAppConfig (Project, [Name], [Value]) 14 | Values ('edw','stagingdb','staging'); 15 | 16 | insert into [dbo].PSAppConfig (Project, [Name], [Value]) 17 | Values ('finance','ftppath','\\financeftpserver\ftp\'); 18 | 19 | insert into [dbo].PSAppConfig (Project, [Name], [Value]) 20 | Values ('finance','dbserver','financesqlsvr'); 21 | 22 | insert into [dbo].PSAppConfig (Project, [Name], [Value]) 23 | Values ('finance','outfolder','\\somepath\outdata\'); 24 | -------------------------------------------------------------------------------- /PPSFDD/Listings/Chapter10/listing-10-16.ps1: -------------------------------------------------------------------------------- 1 | function Verb-UdfNoun 2 | { 3 | <# 4 | .SYNOPSIS 5 | Enter a short description of what the funtion does. 6 | 7 | .DESCRIPTION 8 | Enter a longer description about the function. 9 | 10 | .PARAMETER Parm1 11 | Describe the first parameter. 12 | 13 | .PARAMETER Parm2 14 | Describe the second parameter. 15 | 16 | .INPUTS 17 | Can data be piped into this function?. 18 | 19 | .OUTPUTS 20 | Describe what this function returns. 21 | 22 | .EXAMPLE 23 | C:\PS> Verb-UdfNoun -parm1 "parm1" -parm2 "parm2" 24 | 25 | .LINK 26 | Enter a url to a help topic if available. 27 | 28 | #> 29 | 30 | [CmdletBinding()] 31 | param 32 | ( 33 | [string] $parm1, 34 | [string] $parm2 35 | ) 36 | 37 | # Insert code below... 38 | 39 | } 40 | -------------------------------------------------------------------------------- /PPSFDD/Listings/Chapter03/listing-3-5.ps1: -------------------------------------------------------------------------------- 1 | # Create the geo object... 2 | [psobject]$mygeo = New-Object PSObject 3 | 4 | New-UdfGeoObject ([ref]$mygeo) 5 | 6 | # Since this is a hash table, let's look up a territory by country... 7 | Write-Host "`r`nTranslate Territory directly from Global Object not fully Qualified..." 8 | $mygeo.Territory["Southeast"] 9 | 10 | Write-Host "`r`nTranslate Territory using a custom method..." 11 | $mygeo.GetCountryForTerritory("Southeast") 12 | 13 | write-host "`r`nCurrency Keys..." 14 | write-host $mygeo.currency.Keys 15 | 16 | Write-Host "`r`nCurrency Values..." 17 | write-host $mygeo.currency.Values 18 | 19 | Write-Host "`r`nTranslate currency code to currency name..." 20 | $mygeo.currency["FRF"] 21 | 22 | Write-Host "`r`nLook up currency conversion row for USD to Japanese Yen..." 23 | $mygeo.CurrencyConversion | where-object {$_["ToCurrencyCode"] -eq "JPY" } 24 | 25 | Write-Host "`r`nConvert currency from USD to Japanese Yen..." 26 | $mygeo.ConvertCurrency("JPY", 150.00) 27 | -------------------------------------------------------------------------------- /PPSFDD/Listings/Chapter05/translate/translate.ps1: -------------------------------------------------------------------------------- 1 | 2 | # Translate using machine default... 3 | "Translating using default language..." 4 | Import-LocalizedData -BindingVariable ds # Machine Default - English 5 | 6 | $ds.Sunday 7 | $ds.Monday 8 | $ds.Tuesday 9 | $ds.Wednesday 10 | $ds.Thursday 11 | $ds.Friday 12 | $ds.Saturday 13 | 14 | # Traslate to Spanish... 15 | "" 16 | "Translating to Spain's Spanish..." 17 | Import-LocalizedData -BindingVariable ds -UICulture es-ES # Machine Default - English 18 | 19 | $ds.Sunday 20 | $ds.Monday 21 | $ds.Tuesday 22 | $ds.Wednesday 23 | $ds.Thursday 24 | $ds.Friday 25 | $ds.Saturday 26 | 27 | # Translate to German... 28 | "" 29 | "Translating to Germany's German..." 30 | 31 | Import-LocalizedData -BindingVariable ds -UICulture de-DE # Machine Default - English 32 | 33 | $ds.Sunday 34 | $ds.Monday 35 | $ds.Tuesday 36 | $ds.Wednesday 37 | $ds.Thursday 38 | $ds.Friday 39 | $ds.Saturday 40 | -------------------------------------------------------------------------------- /PPSFDD/Modules/umd_database/scr_wf_as_scheduled_job.ps1: -------------------------------------------------------------------------------- 1 | workflow myworkflow 2 | { 3 | sequence { 4 | "one" 5 | "two" 6 | "three" 7 | } 8 | 9 | parallel 10 | { 11 | 12 | "first parallel statement" 13 | Get-Date 14 | 15 | } 16 | 17 | $collection = "this","is","a","collection" 18 | 19 | foreach -parallel ($item in $collection) 20 | { 21 | $item 22 | } 23 | 24 | inlinescript { Get-ChildItem Env: } 25 | } 26 | 27 | myworkflow 28 | 29 | # See the workflow XAML definition... 30 | (Get-Command myworkflow).XamlDefinition 31 | 32 | # https://www.simple-talk.com/sysadmin/powershell/automating-day-to-day-powershell-admin-tasks---jobs-and-workflow/?utm_source=ssc&utm_medium=publink&utm_content=automatingpstasks 33 | 34 | myworkflow -AsJob | Register-ScheduledJob -ScriptBlock {myworkflow} -Name BryWF1 -RunNow 35 | 36 | Get-Job -id 1 37 | 38 | Get-ScheduledJob -Id 1 39 | 40 | Receive-Job -ID 1 -Keep 41 | 42 | Start-Job -DefinitionName BryWF1 43 | 44 | 45 | 46 | -------------------------------------------------------------------------------- /PPSFDD/Listings/Chapter05/listing-5-12.ps1: -------------------------------------------------------------------------------- 1 | $PSDefaultParameterValues.Add("*:sqlserver","(local)") 2 | $PSDefaultParameterValues.Add("*:sqldatabase","AdventureWorks") 3 | 4 | function Invoke-UdfSQLQuery 5 | { 6 | [CmdletBinding()] 7 | param ( 8 | [string] $sqlserver , # SQL Server 9 | [string] $sqldatabase , # SQL Server Database. 10 | [string] $sqlquery # SQL Query 11 | ) 12 | 13 | $conn = new-object System.Data.SqlClient.SqlConnection("Data Source=$sqlserver;Integrated Security=SSPI;Initial Catalog=$sqldatabase"); 14 | 15 | $command = new-object system.data.sqlclient.sqlcommand($sqlquery,$conn) 16 | 17 | $conn.Open() 18 | 19 | $adapter = New-Object System.Data.sqlclient.sqlDataAdapter $command 20 | $dataset = New-Object System.Data.DataSet 21 | $adapter.Fill($dataset) | Out-Null 22 | 23 | RETURN $dataset.tables[0] 24 | 25 | $conn.Close() 26 | } 27 | 28 | Invoke-UdfSQLQuery -sqlquery 'select top 100 * from person.address' 29 | -------------------------------------------------------------------------------- /PPSFDD/Listings/Chapter08/listing-8-6.ps1: -------------------------------------------------------------------------------- 1 | function Invoke-UdfMyFunctionWithlogging ([string]$parm1, [int]$parm2 = 3, $parm3 ) 2 | { 3 | 4 | "The value of `$parm2 is $parm2" 5 | 6 | if ($parm1) {"Has a value"} else {"No value"} 7 | 8 | if ($parm1 -eq $null) {"No parm passed equals `$null"} else {"No value does not equal `$null"} 9 | 10 | "Let's get the string version of null and try again." 11 | if ($parm1 -eq [string]$null) {"`$null test worked"} else {"A real value was passed"} 12 | 13 | 14 | "Default for `$parm1 is '$parm1'" 15 | "Default for `$parm2 is $parm2" 16 | "Default for `$parm3 is $parm3" 17 | 18 | "Notice that `$null equals `$null" 19 | ($null -eq $null) 20 | 21 | "If we concatenate a $null with other strings, we do not get `$null back" 22 | $myvar = "Bryan " + $null + "Cafferky" 23 | $myvar 24 | 25 | [string]$mystr = $null 26 | "`$null assigned to a string = '$mystr'." 27 | [int]$myint = $null 28 | "`$null assigned to a number = $myint." 29 | 30 | } 31 | 32 | # Call the function… 33 | Invoke-UdfMyFunctionWithlogging 34 | -------------------------------------------------------------------------------- /PPSFDD/Listings/Chapter05/listing-5-6.ps1: -------------------------------------------------------------------------------- 1 | function Invoke-UdfTestValidationArray 2 | { 3 | [cmdletBinding()] 4 | param ( 5 | [parameter(mandatory=$true, 6 | HelpMessage="Enter a string value.")] 7 | [ValidateLength(9,11)] 8 | [ValidatePattern("^\d{3}-?\d{2}-?\d{4}$")] # Pattern for SSN 9 | [ValidateCount(1,3)] 10 | [string[]] $inparm1 11 | ) 12 | 13 | 14 | foreach ($item in $inparm1) { 15 | write-verbose $item 16 | } 17 | } 18 | 19 | Write-Host "Good parameters..." 20 | Invoke-UdfTestValidationArray @("123445678","999-12-1234") -Verbose # Passes validation 21 | write-host "" 22 | 23 | Write-host "Bad parameters, Invalid format..." 24 | Invoke-UdfTestValidationArray @("1234456789","999-12-123488") -Verbose # Fails validation - first element does not match pattern. 25 | write-host "" 26 | 27 | Write-host "Bad parameters, Too many elements in the array..." 28 | Invoke-UdfTestValidationArray @("123445678","999-12-1234","123-22-8888","999121234") -Verbose 29 | -------------------------------------------------------------------------------- /PPSFDD/Listings/Chapter05/listing-5-17.ps1: -------------------------------------------------------------------------------- 1 | function Invoke-UdfTestMandatoryParameters3 2 | { 3 | [cmdletBinding()] 4 | param ( 5 | [Parameter(Mandatory = $true)] 6 | [AllowEmptyString()] 7 | [string] $p_string, 8 | [Parameter(Mandatory = $true)] 9 | [ValidateNotNull()] 10 | [System.Nullable[int]] $p_int, 11 | [Parameter(Mandatory = $true)] 12 | [ValidateNotNull()] 13 | [bool] $p_bool, 14 | [Parameter(Mandatory = $true)] 15 | [array] $p_array, 16 | [Parameter(Mandatory = $true)] 17 | [hashtable] $p_hash 18 | ) 19 | "String is : $p_string" 20 | "Int is: $p_int" 21 | "Boolean is: $p_bool" 22 | "Array is: $p_array" 23 | Write-Host "Hashtable is: " 24 | $p_hash 25 | } 26 | 27 | # Let’s test the above change with the two statements below. 28 | Invoke-UdfTestMandatoryParameters3 -p_string '' -p_int 0 -p_bool $null # Rejected 29 | 30 | Invoke-UdfTestMandatoryParameters3 -p_string '' -p_int 0 -p_bool $false # Accepted 31 | -------------------------------------------------------------------------------- /PPSFDD/Listings/Chapter05/listing-5-19.ps1: -------------------------------------------------------------------------------- 1 | function Invoke-UdfTestManualValidation 2 | { 3 | [cmdletBinding()] 4 | param ( 5 | [string] $p_string, 6 | [System.Nullable[int]] $p_int, 7 | [bool] $p_bool, 8 | [array] $p_array, 9 | [hashtable] $p_hash 10 | ) 11 | 12 | if ($p_string.Length -eq 0) { Write-Host -foregroundcolor Red 'Specify a string value please.'; return } 13 | 14 | if ($p_int -le 0) { Write-Host -foregroundcolor Red 'Specify an integer greater than zero please.'; return } 15 | 16 | if ($p_array.Count -eq 0 ) { Write-Host -foregroundcolor Red 'Specify an array with at least one element please.'; return } 17 | 18 | if ($p_hash.Count -eq 0) { Write-Host -foregroundcolor Red 'Specify a hashtable with at least one element please.'; return } 19 | 20 | "String is : $p_string" 21 | "Int is: $p_int" 22 | "Boolean is: $p_bool" 23 | "Array is: $p_array" 24 | Write-Host "Hashtable is: " 25 | $p_hash 26 | } 27 | 28 | Invoke-UdfTestManualValidation -p_string 'x' -p_int 1 -p_array @(1) -p_hash @{"a"="Test"} 29 | 30 | -------------------------------------------------------------------------------- /PPSFDD/Listings/Chapter03/listing-3-10.ps1: -------------------------------------------------------------------------------- 1 | # Check if the SQL module is loaded and if not, load it. 2 | if(-not(Get-Module -name "sqlps")) 3 | { 4 | Import-Module "sqlps" 5 | } 6 | 7 | set-location SQLSERVER:\SQL\BryanCafferkyPC\DEFAULT\Databases\Adventureworks\Tables 8 | 9 | $territoryrs = Invoke-Sqlcmd -Query "SELECT [StateProvinceID],[TaxType],[TaxRate],[Name] FROM [AdventureWorks].[Sales].[SalesTaxRate];" -QueryTimeout 3 10 | 11 | $excel = New-Object -ComObject Excel.Application 12 | 13 | $excel.Visible = $true # Show us what’s happening 14 | 15 | $workbook = $excel.Workbooks.Add() # Create a new worksheet 16 | 17 | $sheet = $workbook.ActiveSheet # and make it the active worksheet. 18 | 19 | $counter = 0 20 | 21 | # Load the worksheet 22 | foreach ($item in $territoryrs) { 23 | 24 | $counter++ 25 | 26 | $sheet.cells.Item($counter,1) = $item.StateProvinceID 27 | $sheet.cells.Item($counter,2) = $item.TaxType 28 | $sheet.cells.Item($counter,3) = $item.TaxRate 29 | $sheet.cells.Item($counter,4) = $item.Name 30 | } 31 | 32 | # Exporting Excel data is as easy as... 33 | $sheet.SaveAs("taxrates.csv", 6) 34 | -------------------------------------------------------------------------------- /PPSFDD/Listings/Chapter03/listing-3-9.ps1: -------------------------------------------------------------------------------- 1 | function Out-UdfHTML ([string] $p_headingbackcolor, [switch] $AlternateRows) 2 | { 3 | if ($AlternateRows) {$tr_alt = "TR:Nth-Child(Even) {Background-Color: #dddddd;}"} 4 | 5 | $format = @" 6 | 13 | "@ 14 | 15 | RETURN $format 16 | } 17 | 18 | # Code to call the function… 19 | $datapath = $env:HOMEDRIVE + $env:HOMEPATH + "\Documents\" 20 | 21 | $instates = Import-CSV ($datapath + “state_table.csv") 22 | 23 | $instates | Select-Object -Property name, abbreviation, country, census_region_name | 24 | where-object -Property census_region_name -eq "Northeast" | 25 | ConvertTo-HTML -Head (Out-UdfHTML "lightblue" -AlternateRows) -Pre "

State List

" -Post ("

As of " + (Get-Date) + "

") | 26 | Out-File MyReport.HTML 27 | 28 | Invoke-Item MyReport.HTML 29 | -------------------------------------------------------------------------------- /PPSFDD/Listings/Chapter05/listing-5-15.ps1: -------------------------------------------------------------------------------- 1 | function Invoke-UdfTestMandatoryParameters2 2 | { 3 | [cmdletBinding()] 4 | param ( 5 | [Parameter(Mandatory = $true)] 6 | [AllowEmptyString()] 7 | [string] $p_string, 8 | [Parameter(Mandatory = $true)] 9 | [int] $p_int, 10 | [Parameter(Mandatory = $true)] 11 | [bool] $p_bool, 12 | [Parameter(Mandatory = $true)] 13 | [array] $p_array, 14 | [Parameter(Mandatory = $true)] 15 | [hashtable] $p_hash 16 | ) 17 | "String is : $p_string" 18 | "Int is: $p_int" 19 | "Boolean is: $p_bool" 20 | "Array is: $p_array" 21 | Write-Host "Hashtable is: " 22 | $p_hash 23 | } 24 | 25 | # By adding the AllowEmptyString attribute, we get the desired behavior. Let’s try a few calls to test this. 26 | 27 | Invoke-UdfTestMandatoryParameters2 # Will be prompted for parameter values. 28 | 29 | Invoke-UdfTestMandatoryParameters2 -p_string '' # Parameter passes validation. 30 | 31 | Invoke-UdfTestMandatoryParameters -p_string $null # Parameter fails validation. 32 | -------------------------------------------------------------------------------- /PPSFDD/Listings/Chapter12/listing-12-2.ps1: -------------------------------------------------------------------------------- 1 | function Invoke-UdfSQLAgentJob 2 | { 3 | 4 | [CmdletBinding()] 5 | param ( 6 | [string]$sqlserverpath, 7 | [string]$jobfilter = '*' 8 | ) 9 | # Import the SQL Server module 10 | if(-not(Get-Module -name "sqlps")) 11 | { 12 | Import-Module "sqlps" -DisableNameChecking 13 | } 14 | 15 | # Set where you are in SQL Server... 16 | set-location $sqlserverpath 17 | 18 | while ($true) 19 | { 20 | 21 | $jobname = $null 22 | 23 | $jobname = Get-ChildItem | 24 | Select-Object -Property Name, Description, LastRunDate, LastRunOutcome | 25 | Where-Object {$_.name -like "$jobfilter*"} | 26 | Out-GridView -Title "Select a Job to Run" -OutputMode Single 27 | 28 | If (!$jobname) { Break } 29 | 30 | $jobobject = Get-ChildItem | where-object {$_.name -eq $jobname.Name} 31 | 32 | $jobobject.start() 33 | 34 | } 35 | 36 | } 37 | <# Example call...change path to your SQL Server Instance #> 38 | Invoke-UdfSQLAgentJob -sqlserverpath 'SQLSERVER:\SQL\BryanCafferkyPC\DEFAULT\JobServer\Jobs\' 39 | -------------------------------------------------------------------------------- /PPSFDD/Listings/Chapter05/listing-5-16.ps1: -------------------------------------------------------------------------------- 1 | function Invoke-UdfTestMandatoryParameters2 2 | { 3 | [cmdletBinding()] 4 | param ( 5 | [Parameter(Mandatory = $true)] 6 | [AllowEmptyString()] 7 | [string] $p_string, 8 | [Parameter(Mandatory = $true)] 9 | [ValidateNotNull()] 10 | [System.Nullable[int]] $p_int, 11 | [Parameter(Mandatory = $true)] 12 | [bool] $p_bool, 13 | [Parameter(Mandatory = $true)] 14 | [array] $p_array, 15 | [Parameter(Mandatory = $true)] 16 | [hashtable] $p_hash 17 | ) 18 | "String is : $p_string" 19 | "Int is: $p_int" 20 | "Boolean is: $p_bool" 21 | "Array is: $p_array" 22 | Write-Host "Hashtable is: " 23 | $p_hash 24 | } 25 | # Now let’s test the function passing a null for $p_int. 26 | Invoke-UdfTestMandatoryParameters2 -p_string '' -p_int $null 27 | 28 | # As expected, the null value is rejected. Now let’s try passing a zero into $p_int. 29 | 30 | Invoke-UdfTestMandatoryParameters2 -p_string '' -p_int 0 31 | # The zero value is accepted so we are prompted for $p_bool. Just press Control+Break to exit the prompt. 32 | -------------------------------------------------------------------------------- /PPSFDD/Listings/Chapter07/listing-7-4.sql: -------------------------------------------------------------------------------- 1 | USE [AdventureWorks] 2 | GO 3 | 4 | SET ANSI_NULLS ON 5 | SET QUOTED_IDENTIFIER ON 6 | GO 7 | 8 | Create PROCEDURE [HumanResources].[uspUpdateEmployeePersonalInfoPS] 9 | @BusinessEntityID [int], 10 | @NationalIDNumber [nvarchar](15), 11 | @BirthDate [datetime], 12 | @MaritalStatus [nchar](1), 13 | @Gender [nchar](1), 14 | @JobTitle [nvarchar](50) output, 15 | @HireDate [date] output, 16 | @VacationHours [smallint] output 17 | WITH EXECUTE AS CALLER 18 | AS 19 | BEGIN 20 | SET NOCOUNT ON; 21 | 22 | BEGIN TRY 23 | UPDATE [HumanResources].[Employee] 24 | SET [NationalIDNumber] = @NationalIDNumber 25 | ,[BirthDate] = @BirthDate 26 | ,[MaritalStatus] = @MaritalStatus 27 | ,[Gender] = @Gender 28 | WHERE [BusinessEntityID] = @BusinessEntityID; 29 | 30 | select @JobTitle = JobTitle, @HireDate = HireDate, @VacationHours = VacationHours 31 | from [HumanResources].[Employee] 32 | where [BusinessEntityID] = @BusinessEntityID; 33 | 34 | END TRY 35 | BEGIN CATCH 36 | EXECUTE [dbo].[uspLogError]; 37 | END CATCH; 38 | END; 39 | 40 | GO 41 | -------------------------------------------------------------------------------- /PPSFDD/Listings/Chapter11/listing-11-2.ps1: -------------------------------------------------------------------------------- 1 | Import-Module umd_etl_functions 2 | # State Code List #> 3 | $global:referencepath = $env:HomeDrive + $env:HOMEPATH + "\Documents\" 4 | 5 | $salestax = Import-CSV ($global:referencepath + "StateSalesTaxRates.csv") 6 | 7 | <# Define the mapping... #> 8 | $mappingset = @() # Create a collection object. 9 | $mappingset += (Add-UdfMapping "StateCode" "StateProvinceCD" "'" $true) 10 | $mappingset += (Add-UdfMapping "SalesTaxRate" "StateProvinceSalesTaxRate" "" $false) 11 | 12 | Import-Module umd_database 13 | 14 | <# Define the SQL Server Target #> 15 | [psobject] $SqlServer1 = New-Object psobject 16 | New-UdfConnection ([ref]$SqlServer1) 17 | 18 | $SqlServer1.ConnectionType = 'ADO' 19 | $SqlServer1.DatabaseType = 'SqlServer' 20 | $SqlServer1.Server = '(local)' 21 | $SqlServer1.DatabaseName = 'Development' 22 | $SqlServer1.UseCredential = 'N' 23 | $SqlServer1.SetAuthenticationType('Integrated') 24 | $SqlServer1.BuildConnectionString() 25 | 26 | # Load the table… 27 | $SqlServer1.RunSQL("truncate table [dbo].[StateSalesTaxRate]", $false) 28 | $salestax | Invoke-UdfSQLDML -Mapping $mappingset -DmlOperation "Insert" -Destinationtablename "dbo.StateSalesTaxRate" -Connection $SqlServer1 -Verbose 29 | -------------------------------------------------------------------------------- /PPSFDD/Modules/umd_database/connectionstrings.txt: -------------------------------------------------------------------------------- 1 | "Type","Platform","AuthenticationType","ConnectionString" 2 | "ADO","SqlServer","Integrated","Data Source=$server;Integrated Security=SSPI;Initial Catalog=$databasename" 3 | "ADO","SqlServer","Logon","Data Source=$server;Persist Security Info=False;IntegratedSecurity=false;Initial Catalog=$databasename;User ID=$userid;Password=$password" 4 | "ADO","SqlServer","Credential","Data Source=$server;Persist Security Info=False;Initial Catalog=$databasename" 5 | "ADO","Azure","Logon","Data Source=$server;User ID=$userid;Password=$password;Initial Catalog=$databasename;Trusted_Connection=False;TrustServerCertificate=False;Encrypt=True;" 6 | "ODBC","PostgreSQL","DSNLess","Driver={$driver};Server=$server;Port=5432;Database=$databasename;Uid=$userid;Pwd=$password;SSLmode=disable;ReadOnly=0;" 7 | "ODBC","PostgreSQL","DSN","DSN=$dsn;SSLmode=disable;ReadOnly=0;" 8 | "ODBC","SqlServer","DSNLess","Driver={$driver};Server=$server;Port=5432;Database=$databasename;Uid=$userid;Pwd=$password;SSLmode=disable;ReadOnly=0;" 9 | "ADO","Access","DSNLess","Provider=Microsoft.ACE.OLEDB.12.0;Data Source=$databasename;Persist Security Info=False;" 10 | "ODBC","Access","DSNLess","Driver={$driver};Dbq=$databasename;Uid=Admin;Pwd=;" 11 | 12 | 13 | 14 | 15 | -------------------------------------------------------------------------------- /PPSFDD/Listings/Chapter05/listing-5-18.ps1: -------------------------------------------------------------------------------- 1 | function Invoke-UdfTestMandatoryParameters3 2 | { 3 | [cmdletBinding()] 4 | param ( 5 | [Parameter(Mandatory = $true)] 6 | [AllowEmptyString()] 7 | [string] $p_string, 8 | [Parameter(Mandatory = $true)] 9 | [ValidateNotNull()] 10 | [System.Nullable[int]] $p_int, 11 | [Parameter(Mandatory = $true)] 12 | [ValidateNotNull()] 13 | [bool] $p_bool, 14 | [Parameter(Mandatory = $true)] 15 | [AllowEmptyCollection()] 16 | [array] $p_array, 17 | [Parameter(Mandatory = $true)] 18 | [hashtable] $p_hash 19 | ) 20 | "String is : $p_string" 21 | "Int is: $p_int" 22 | "Boolean is: $p_bool" 23 | "Array is: $p_array" 24 | Write-Host "Hashtable is: " 25 | $p_hash 26 | } 27 | 28 | # Let’s test the above function with the statements below. 29 | Invoke-UdfTestMandatoryParameters3 -p_string '' -p_int 0 -p_bool $false -p_array $null 30 | 31 | # The above statement will cause PowerShell to reject the $p_array parameter. 32 | # Let’s try the call with an empty array as shown below. 33 | Invoke-UdfTestMandatoryParameters3 -p_string '' -p_int 0 -p_bool $false -p_array @() 34 | -------------------------------------------------------------------------------- /PPSFDD/Listings/Chapter05/listing-5-20.ps1: -------------------------------------------------------------------------------- 1 | function Invoke-UdfAddValue 2 | { 3 | [cmdletBinding(SupportsShouldProcess=$false)] 4 | param ( 5 | [Parameter(Mandatory = $true, Position = 0, ParameterSetName = "number")] 6 | [int]$number1, 7 | [Parameter(Mandatory = $true, Position = 1, ParameterSetName = "number")] 8 | [int]$number2, 9 | [Parameter(Mandatory = $true, Position = 0, ParameterSetName = "string")] 10 | [string]$string1, 11 | [Parameter(Mandatory = $true, Position = 1, ParameterSetName = "string")] 12 | [string]$string2, 13 | [Parameter(Mandatory = $true, Position = 0, ParameterSetName = "datetime")] 14 | [datetime]$datetime1, 15 | [Parameter(Mandatory = $true, Position = 1, ParameterSetName = "datetime")] 16 | [int]$days 17 | ) 18 | 19 | Switch ($PScmdlet.ParameterSetName) 20 | { 21 | "number" { "Added Value = " + ($number1 + $number2) } 22 | "string" { "Added Value = " + $string1 + $string2 } 23 | "datetime" { "Added Value = " + $datetime1.AddDays($days) } 24 | } 25 | } 26 | 27 | Invoke-UdfAddValue 1 2 28 | Invoke-UdfAddValue "one" "two" 29 | Invoke-UdfAddValue (Get-Date) 5 30 | -------------------------------------------------------------------------------- /PPSFDD/Listings/Chapter02/listing-2-3.ps1: -------------------------------------------------------------------------------- 1 | <# Author: Bryan Cafferky Date: 2013-11-29 2 | Purpose: Speaks the input... 3 | Fun using SAPI - the text to speech thing.... 4 | #> 5 | 6 | # Variable declarations… 7 | $speaker = new-object -com SAPI.SpVoice # Since PowerShell defaults variables to objects, no need to declare it. 8 | 9 | [string]$saythis = "" # Note: If you don't declare the type as string, you won't have the string methods available to you. 10 | 11 | [string] $option = "x" 12 | 13 | while ($option.toUpper() -ne "S") 14 | { # --> Open Brace defines the start of a code block. 15 | $option = read-host "Enter d for read directory, i for say input, s to stop" 16 | 17 | if ($option -eq "d") 18 | { 19 | $saythis = Get-ChildItem 20 | $saythis = $saythis.substring(1, 50) 21 | } 22 | elseif ($option -eq "i") { 23 | $saythis = read-host "What would you like me to say?" 24 | } 25 | else { 26 | $saythis = "Stopping the program." 27 | } 28 | 29 | $speaker.Speak($saythis, 1) | out-null # We are piping the return value to null, i.e. like void is C# 30 | } # --> Closing Brace defines the end of a code block. 31 | -------------------------------------------------------------------------------- /PPSFDD/Listings/Chapter02/listing-2-5.ps1: -------------------------------------------------------------------------------- 1 | [string] $mystring = " This is a nifty nifty string. " 2 | 3 | # Get a part of the string. 4 | Write-Host $mystring.Substring(0,5) 5 | 6 | # Get the length of the string. 7 | Write-Host $mystring.Length 8 | 9 | # Comparing... 10 | Write-Host $mystring.CompareTo("This is a nifty nifty string.") # 0 = a match and -1 = no match. 11 | Write-Host $mystring.Equals("This is a nifty string.") # returns True or False 12 | 13 | # Search for set of characters in the string. 14 | Write-Host $mystring.Contains("nifty") # returns True or False 15 | 16 | # Does the string end with the characters passed into the method? 17 | Write-Host $mystring.EndsWith(".") # returns True or False 18 | 19 | # insert the set of characters in the second parameterstarting at the position specified in the first parameter. 20 | Write-Host $mystring.Insert(5, "was ") 21 | 22 | # Convert to Upper Case 23 | Write-Host $mystring.ToUpper() 24 | 25 | # Convert to Lower Case 26 | Write-Host $mystring.ToLower() 27 | 28 | # Strip off beginning and trailing spaces. 29 | Write-Host $mystring.Trim() 30 | 31 | # Replace occurences of the set of characters specified in the first parameter with the set in the second parameter. 32 | Write-Host $mystring.Replace("nifty", "swell") 33 | -------------------------------------------------------------------------------- /PPSFDD/Listings/Chapter04/listing-4-1.ps1: -------------------------------------------------------------------------------- 1 | set-location ($env:HOMEDRIVE + $env:HOMEPATH + "\Documents\") 2 | 3 | # Let's use Here strings to create our input files... 4 | 5 | @" 6 | Joe Jones|22 Main Street|Boston|MA|12345 7 | Mary Smith|33 Mockingbird Lane|Providence|RI|02886 8 | "@ > outfileex1.txt 9 | 10 | @" 11 | Tom Jones|11 Ellison Stree|Newton|MA|12345 12 | Ellen Harris|12 Warick Aveneu|Warwick|RI|02885 13 | "@ > outfileex2.txt 14 | 15 | # We could make these parameters but we'll just use variables so the code stands alone... 16 | $sourcepath = $env:HOMEDRIVE + $env:HOMEPATH + "\Documents" 17 | $filter = "outfileex*.txt" 18 | 19 | $filelist = Get-ChildItem -Path $sourcepath -filter $filter 20 | 21 | $targetpathfile = $env:HOMEDRIVE + $env:HOMEPATH + "\Documents\outmergedex.txt" 22 | 23 | try 24 | { 25 | Remove-Item $targetpathfile -ErrorAction Stop 26 | } 27 | catch 28 | { 29 | "Error removing prior files." 30 | Write-Host $_.Exception.Message 31 | } 32 | finally 33 | { 34 | Write-Host "Done removing file if it existed." 35 | "out files merged at " + (Get-Date) | out-file outmerge.log -append 36 | } 37 | 38 | foreach ($file in $filelist) 39 | { 40 | "Merging file $file..." 41 | $fc = Get-Content $file 42 | foreach ($line in $fc) {$line + "|" + $file.name >> $targetpathfile } 43 | } 44 | 45 | -------------------------------------------------------------------------------- /PPSFDD/Listings/Chapter10/listing-10-11.ps1: -------------------------------------------------------------------------------- 1 | Import-Module umd_database 2 | 3 | function Set-UdfConfigurationFromDatabase 4 | { 5 | [CmdletBinding()] 6 | param ( 7 | [string] $sqlserver, 8 | [string] $sqldb, 9 | [string] $sqltable 10 | ) 11 | 12 | [psobject] $config = New-Object psobject 13 | 14 | $projects = Invoke-UdfSQLQuery -sqlserver $sqlserver ` 15 | -sqldatabase $sqldb ` 16 | -sqlquery "select distinct project from $sqltable;" 17 | 18 | $configrows = Invoke-UdfSQLQuery -sqlserver $sqlserver -sqldatabase $sqldb ` 19 | -sqlquery "select * from $sqltable order by project, name;" 20 | 21 | foreach ($project in $projects) 22 | { 23 | $configlist = @{} 24 | 25 | foreach ($configrow in $configrows) 26 | { 27 | if ($configrow.project -eq $project.project ) 28 | { $configlist.Add($configrow.name, $configrow.value) } 29 | } 30 | 31 | # Add the noteproperty with the configuration hashtable as the value. 32 | $config | Add-Member -MemberType NoteProperty -Name $project.project -Value $configlist 33 | } 34 | 35 | Return $config 36 | } 37 | 38 | Set-UdfConfigurationFromDatabase '(local)' 'Development' 'dbo.PSAppConfig' 39 | -------------------------------------------------------------------------------- /PPSFDD/Listings/Chapter07/listing-7-8.ps1: -------------------------------------------------------------------------------- 1 | Import-Module umd_database 2 | 3 | [psobject] $myconnection = New-Object psobject 4 | New-UdfConnection([ref]$myconnection) 5 | $myconnection | Get-Member 6 | 7 | $myconnection.ConnectionType = 'ADO' 8 | $myconnection.DatabaseType = 'SqlServer' 9 | $myconnection.Server = '(local)' 10 | $myconnection.DatabaseName = 'AdventureWorks' 11 | $myconnection.UseCredential = 'N' 12 | $myconnection.UserID = 'bryan' 13 | $myconnection.Password = 'password' 14 | 15 | $myconnection.SetAuthenticationType('Integrated') 16 | 17 | $myconnection.BuildConnectionString() 18 | 19 | $parmset = @() # Create a collection object. 20 | # Add the parameters we need to use... 21 | $parmset += (Add-UdfParameter "@BusinessEntityID" "Input" "1" "int32" 0) 22 | $parmset += (Add-UdfParameter "@NationalIDNumber" "Input" "295847284" "string" 15) 23 | $parmset += (Add-UdfParameter "@BirthDate" "Input" "1964-02-02" "date" 0) 24 | $parmset += (Add-UdfParameter "@MaritalStatus" "Input" "S" "string" 1) 25 | $parmset += (Add-UdfParameter "@Gender" "Input" "M" "string" 1) 26 | $parmset += (Add-UdfParameter "@JobTitle" "Output" "" "string" 50) 27 | $parmset += (Add-UdfParameter "@HireDate" "Output" "" "date" 0) 28 | $parmset += (Add-UdfParameter "@VacationHours" "Output" "" "int16" 0) 29 | 30 | $myconnection.RunStoredProcedure('[HumanResources].[uspUpdateEmployeePersonalInfoPS]', $parmset) 31 | $parmset # Lists the output parameters 32 | -------------------------------------------------------------------------------- /PPSFDD/Listings/Chapter10/listing-10-21.ps1: -------------------------------------------------------------------------------- 1 | Import-Module umd_etl_functions 2 | 3 | # Wait for the files... 4 | Wait-UdfFileCreation $global:ftppath -Verbose 5 | 6 | # Notify users the job has started using Outlook... 7 | Send-UdfMail -Server $global:mailserver -From $global:fromemail -To $global:toemail ` 8 | –Subject "ETL Job: Sales Load has started" –Body "The ETL Job: Sales Load has started." ` 9 | –Port $global:emailport -usecredential $global:emailaccount –Password $global:emailpw 10 | 11 | # Copy the files... 12 | Copy-UdfFile $ global:ftppath $global:inbound -overwrite 13 | 14 | $filelist = Get-ChildItem $global:zippath 15 | 16 | # Unzip the files... 17 | Foreach ($file in $filelist) 18 | { 19 | Expand-UdfFile $file.FullName $global:unzippedpath -force 20 | } 21 | 22 | # Add file name to file... 23 | Add-UdfColumnNameToFile $global:unzippedpath $global:processpath "sales*.csv" 24 | 25 | # Load the files... 26 | Invoke-UdfSalesTableLoad $global:processpath "sales*.csv" -Verbose 27 | 28 | # Archive files... 29 | Move-UdfFile $global:ftppath $global:archivepath -overwrite 30 | 31 | # Notify users the job has finished... 32 | Send-UdfMail -Server $global:mailserver -From $global:fromemail -To $global:toemail ` 33 | –Subject "ETL Job: Sales Load has ended" –Body "The ETL Job: Sales Load has ended." ` 34 | –Port $global:emailport -usecredential $global:emailaccount –Password $global:emailpw 35 | -------------------------------------------------------------------------------- /PPSFDD/Listings/Chapter05/listing-5-1.ps1: -------------------------------------------------------------------------------- 1 | function Invoke-UdfFileAction { 2 | [cmdletBinding(SupportsShouldProcess=$true)] 3 | param ( 4 | [Parameter(Mandatory = $true, Position = 0, ParameterSetName = "delete")] 5 | [switch]$dodelete, 6 | [Parameter(Mandatory = $true, Position = 1, ParameterSetName = "delete")] 7 | [string]$filetodelete, 8 | [Parameter(Mandatory = $true, Position = 0, ParameterSetName = "copy")] 9 | [switch]$docopy, 10 | [Parameter(Mandatory = $true, Position = 1, ParameterSetName = "copy")] 11 | [string]$filefrom, 12 | [Parameter(Mandatory = $true, Position = 2, ParameterSetName = "copy")] 13 | [string]$fileto 14 | ) 15 | 16 | if ($dodelete) 17 | { 18 | try 19 | { 20 | Remove-Item $filetodelete -ErrorAction Stop 21 | write-host "Deleted $filetodelete ." 22 | } 23 | catch 24 | { 25 | "Error: Problem deleting old file." 26 | } 27 | } 28 | 29 | if ($docopy) 30 | { 31 | try 32 | { 33 | Copy-Item $filefrom $fileto -ErrorAction Stop 34 | write-host "File $filefrom copied to $fileto." 35 | } 36 | catch 37 | { 38 | "Error: Problem copying file." 39 | } 40 | } 41 | 42 | } 43 | 44 | "somestuff" > somedata.txt # Creates a file. 45 | Invoke-UdfFileAction -dodelete 'somedata.txt' -Whatif 46 | 47 | Invoke-UdfFileAction -docopy 'copydata.txt' 'newcopy.txt' -Whatif -------------------------------------------------------------------------------- /PPSFDD/Listings/Chapter09/listing-9-1.ps1: -------------------------------------------------------------------------------- 1 | Import-Module umd_etl_functions -Force 2 | Clear-Host 3 | 4 | $rootfolder = $env:HOMEDRIVE + $env:HOMEPATH + "\Documents" 5 | $ftppath = $rootfolder + "\FTP\sales_*.zip" 6 | $inbound = $rootfolder + "\Inbound\" 7 | $zippath = $inbound + "\sales_*.zip" 8 | $unzippedpath = $rootfolder + "\unzipped\" 9 | $processpath = $rootfolder + "\Process\" 10 | $archivepath = $rootfolder + "\Archive\" 11 | 12 | # Wait for the files... 13 | Wait-UdfFileCreation $ftppath -Verbose 14 | 15 | # Notify users the job has started using Outlook... 16 | Send-UdfMail "smtp.live.com" "emailaddress@msn.com" "emailaddress@msn.com" "ETL Job: Sales Load has Started" "The ETL Job: Sales Load has started." "587" -usecredential "emailaddress@msn.com" "password" 17 | 18 | # Copy the files... 19 | Copy-UdfFile $ftppath $inbound -overwrite 20 | 21 | $filelist = Get-ChildItem $zippath 22 | 23 | # Unzip the files... 24 | Foreach ($file in $filelist) 25 | { 26 | Expand-UdfFile $file.FullName $unzippedpath -force 27 | } 28 | 29 | # Add file name to file... 30 | Add-UdfColumnNameToFile $unzippedpath $processpath "sales*.csv" -Verbose 31 | 32 | # Load the files... 33 | Invoke-UdfSalesTableLoad $processpath "sales*.csv" -Verbose 34 | 35 | # Archive files... 36 | Move-UdfFile $ftppath $archivepath -overwrite 37 | 38 | # Notify users the job has finished... 39 | Send-UdfMail "smtp.live.com" "emailaddress@msn.com" "emailaddress@msn.com" "ETL Job: Sales Load has ended" "The ETL Job: Sales Load has ended." "587" -usecredential "emailaddress@msn.com" "password" 40 | -------------------------------------------------------------------------------- /PPSFDD/Listings/Chapter10/listing-10-1.ps1: -------------------------------------------------------------------------------- 1 | # Some script 2 | $global:myvar = 'global' # All code in the session can access this. 3 | "`$myvar is at the global scope - value is '$myvar'" 4 | 5 | 'Creating a new variable $myvar' 6 | $myvar = 'script' # Creates a new variable which hides the global variable. 7 | "By default `$myvar is at the script scope - value is '$script:myvar'" 8 | 9 | "We can still access the global variable using the scope prefix `$global:myvar - value is '$global:myvar'" 10 | 11 | function Invoke-UdfSomething 12 | { 13 | "Now in the function..." 14 | "`$myvar in the function sees the script scope - value is '$myvar'" 15 | 16 | # If we assign a value to $myvar we create a new variable in the function scope. 17 | 'We assign a value to $myvar creating a function scoped variable' 18 | $myvar = 'function' 19 | 20 | "The default scope for `$myvar is now at the function level - value is '$myvar'" 21 | 22 | "within the function - can use scope prefix to see global variable `$global:myvar - is $global:myvar" 23 | 24 | "within the function - can use scope prefix to see script variable `$script:myvar - is $script:myvar" 25 | 26 | "within the function - local scope is function - `$myvar is $myvar" 27 | 28 | } 29 | 30 | Invoke-UdfSomething # Show variable scope in function 31 | 32 | "Out of the function now..." 33 | # Can we still access the global scope? 34 | 'We can still see the global scope...' 35 | get-variable myvar -scope global 36 | "`r`nAnd we can still see the script scope..." 37 | get-variable myvar -scope script # Local scope is script 38 | -------------------------------------------------------------------------------- /PPSFDD/Listings/Chapter05/listing-5-23.ps1: -------------------------------------------------------------------------------- 1 | function Invoke-UdfFileAction { 2 | [cmdletBinding()] 3 | param ( 4 | [Parameter(Mandatory = $true, Position = 0, ParameterSetName = "delete")] 5 | [switch]$dodelete, 6 | [Parameter(Mandatory = $true, Position = 1, ParameterSetName = "delete")] 7 | [string]$filetodelete, 8 | [Parameter(Mandatory = $true, Position = 0, ParameterSetName = "copy")] 9 | [switch]$docopy, 10 | [Parameter(Mandatory = $true, Position = 1, ParameterSetName = "copy")] 11 | [string]$filefrom, 12 | [Parameter(Mandatory = $true, Position = 2, ParameterSetName = "copy")] 13 | [string]$fileto 14 | ) 15 | 16 | if ($dodelete) 17 | { 18 | try 19 | { 20 | Remove-Item $filetodelete -ErrorAction Stop 21 | write-host "Deleted $filetodelete ." 22 | } 23 | catch 24 | { 25 | "Error: Problem deleting old file." 26 | } 27 | } 28 | 29 | if ($docopy) 30 | { 31 | try 32 | { 33 | Copy-Item $filefrom $fileto -ErrorAction Stop 34 | write-host "File $filefrom copied to $fileto." 35 | } 36 | catch 37 | { 38 | "Error: Problem copying file." 39 | } 40 | } 41 | } 42 | 43 | # The code below shows some examples of calling the function Invoke-UdfFileAction using the different parameter sets. 44 | "somestuff" > somedata.txt 45 | 46 | Invoke-UdfFileAction -dodelete 'somedata.txt' 47 | 48 | "somestuff" > copydata.txt 49 | Invoke-UdfFileAction -docopy 'copydata.txt' 'newcopy.txt' 50 | -------------------------------------------------------------------------------- /PPSFDD/Listings/Chapter03/listing-3-6.ps1: -------------------------------------------------------------------------------- 1 | function New-UdfZipCodeObject { 2 | 3 | [CmdletBinding()] 4 | param ( 5 | [ref]$zipobject 6 | ) 7 | 8 | # Load Zip Codes 9 | 10 | $zipcodes = Import-CSV ($env:HOMEDRIVE + $env:HOMEPATH + "\Documents\" + "free-zipcode-database.csv") 11 | 12 | $zipobject.value | Add-Member -MemberType noteproperty ` 13 | -Name ZipCodeData ` 14 | -Value $zipcodes 15 | 16 | # Find Zip Codes... 17 | 18 | $bgetdataforzip = @' 19 | param([string] $zip) 20 | 21 | RETURN $this.ZipCodeData | where-object {$_.Zipcode -eq "$zip" } 22 | '@ 23 | 24 | $sgetdataforzip = [scriptblock]::create($bgetdataforzip) 25 | 26 | $zipobject.value | Add-Member -MemberType scriptmethod ` 27 | -Name GetZipDetails ` 28 | -Value $sgetdataforzip ` 29 | -Passthru 30 | } 31 | 32 | # Code to use the function... 33 | 34 | New-UdfZipCodeObject([ref]$mygeo) 35 | 36 | # Note that we do not declare the $mygeo object variable as it already exists. 37 | # We pass it into the function to add zip code functionality, using the REF type again so the function can add to the object. 38 | # Let’s test the features added using the following code: 39 | Write-Host "`r`nVerify a Zip Code is valid..." 40 | $mygeo.ZipCodeData.Zipcode.Contains("02886") 41 | 42 | Write-Host "`r`nGet the details for a zip code..." 43 | $mygeo.GetZipDetails("02886") 44 | 45 | Write-Host "`r`nGet the city or cities for a zip..." 46 | $mygeo.GetZipDetails("02886").City 47 | -------------------------------------------------------------------------------- /PPSFDD/Listings/Chapter03/listing-3-2.ps1: -------------------------------------------------------------------------------- 1 | function Invoke-UdfShownOpenFileDialog { 2 | <# 3 | .SYNOPSIS 4 | Opens a Windows Open File Common Dialog. 5 | .DESCRIPTION 6 | Use this function when you need to provide a selection of files to open. 7 | .NOTES 8 | Author: Bryan Cafferky, BPC Global Solutions, LLC 9 | 10 | .PARAMETER initdir 11 | The directory to be displayed when the dialog opens. 12 | 13 | .PARAMETER title 14 | This is the title to be put in the window title bar. 15 | 16 | .PARAMETER filter 17 | The file filter you want applied such as *.csv in the format 'All files (*.*)| *.*' . 18 | 19 | .PARAMETER multifile 20 | Switch that is passed enables multiple files to be selected. 21 | 22 | .LINK 23 | Place link here. 24 | .EXAMPLE 25 | ufn_show_openfiledialog "C:\" "All files (*.*)| *.*" -multifile 26 | .EXAMPLE 27 | ufn_show_openfiledialog "C:\" "All files (*.*)| *.*" 28 | #> 29 | 30 | [CmdletBinding()] 31 | Param( 32 | [Parameter(Mandatory=$True,Position=0)] 33 | [string]$initdir, 34 | 35 | [Parameter(Mandatory=$True,Position=1)] 36 | [string]$filter, 37 | 38 | [switch]$multifile 39 | ) 40 | 41 | [System.Reflection.Assembly]::LoadWithPartialName("System.windows.forms") | Out-Null 42 | $OpenFileDialog = New-Object System.Windows.Forms.OpenFileDialog 43 | $OpenFileDialog.initialDirectory = $initdir 44 | $OpenFileDialog.filter = $filter 45 | 46 | If ($multifile) 47 | { 48 | $OpenFileDialog.Multiselect = $true 49 | } 50 | 51 | $OpenFileDialog.ShowDialog() | Out-Null 52 | $OpenFileDialog.filename 53 | 54 | } 55 | 56 | get-help Invoke-UdfShownOpenFileDialog -full 57 | -------------------------------------------------------------------------------- /PPSFDD/Listings/Chapter04/listing-4-13.ps1: -------------------------------------------------------------------------------- 1 | Import-Module WASP 2 | Import-Module umd_database 3 | 4 | $url = "http://statetable.com/" 5 | 6 | get-process -name iexplore -ErrorAction SilentlyContinue | Stop-Process -Force -ErrorAction SilentlyContinue 7 | $ie = New-Object -comobject InternetExplorer.Application 8 | $ie.visible = $true 9 | $ie.silent = $true 10 | $ie.Navigate( $url ) 11 | 12 | while( $ie.busy){Start-Sleep 1} 13 | Select-Window "iexplore" | Set-WindowActive 14 | 15 | $btn=$ie.Document.getElementById("USA") 16 | $btn.Click() 17 | 18 | while( $ie.busy){Start-Sleep 1} 19 | $btn=$ie.Document.getElementById("major") 20 | $btn.Click() 21 | 22 | while( $ie.busy){Start-Sleep 1} 23 | $btn=$ie.Document.getElementById("true") 24 | $btn.Click() 25 | 26 | while( $ie.busy){Start-Sleep 1} 27 | $btn=$ie.Document.getElementById("current") 28 | $btn.Click() 29 | 30 | while( $ie.busy){Start-Sleep 1} 31 | $btn = $ie.Document.getElementsByTagName('A') | Where-Object {$_.innerText -eq 'Do not include the US Minor Outlying Islands '} 32 | $btn.Click() 33 | 34 | while( $ie.busy){Start-Sleep 1} 35 | $btn=$ie.Document.getElementById("csv") 36 | $btn.Click() 37 | 38 | start-sleep 8 39 | while( $ie.busy){Start-Sleep 1} 40 | Select-Window iexplore | Set-WindowActive | Send-Keys "%S" 41 | 42 | Start-Transaction -RollbackPreference TerminatingError 43 | 44 | $sourcepath = $env:HOMEDRIVE + $env:HOMEPATH + "\downloads\state_table.csv" 45 | $targetpath = $env:HOMEDRIVE + $env:HOMEPATH + "\Documents\state_table.csv" 46 | 47 | Copy-Item $sourcepath $targetpath -UseTransaction 48 | 49 | $CheckFile = Import-CSV $targetpath 50 | 51 | If ($CheckFile.Count -lt 50) { Write-host "Error"; Undo-Transaction } else { "Transaction Committed" ; Complete-Transaction } 52 | -------------------------------------------------------------------------------- /PPSFDD/Listings/Chapter03/listing-3-8.ps1: -------------------------------------------------------------------------------- 1 | function Invoke-UdfSQLScript 2 | ([string] $p_server, [string] $p_dbname, [string] $logpath) 3 | 4 | { 5 | 6 | begin 7 | { 8 | if(-not(Get-Module -name "sqlps")) { Import-Module "sqlps" } 9 | 10 | set-location "SQLSERVER:\SQL\$p_server\DEFAULT\Databases\$p_dbname\" 11 | write-host $p_server $p_dbname 12 | "Deployment Log: Server: $p_server Target Datbase: $p_dbname Date/Time: " ` 13 | + (Get-Date) + "`r`n" > $logpath 14 | # > means create/overwrite and >> means append. 15 | } 16 | 17 | process 18 | { 19 | Try 20 | { 21 | $filepath = $_.fullname # grab this so we can write it out in the Catch block. 22 | $script = Get-Content $_.fullname # Load the script into a variable. 23 | write-host $filepath 24 | Invoke-Sqlcmd -Query "$script ;" -QueryTimeout 3 25 | "Script: $filepath successfully processed. " >> $logpath 26 | } 27 | Catch 28 | { 29 | write-host "Error processing script: $filepath . Deployment aborted." 30 | Continue 31 | } 32 | } 33 | 34 | end 35 | { 36 | "`r`nEnd of Deployment Log: Server: $p_server Target Datbase: $p_dbname Finished Date/Time: " + (Get-Date) + "`r`n" >> $logpath 37 | } 38 | } 39 | 40 | # Lines to call the function. Passing paramters positionally… 41 | 42 | # Change $scriptpath to point to where the SQL scripts are located. 43 | # Change $logpath to where you want the log file created. 44 | cls 45 | $datapath = $env:HOMEDRIVE + $env:HOMEPATH + "\Documents\" 46 | $scriptpath = $datapath + "*.sql" 47 | $logpath = $datapath + "deploy1_log.txt" 48 | 49 | Get-ChildItem -Path $scriptpath | Invoke-UdfSQLScript "(local)" "AdventureWorks" $logpath 50 | -------------------------------------------------------------------------------- /PPSFDD/Listings/Chapter05/listing-5-13.ps1: -------------------------------------------------------------------------------- 1 | function Invoke-UdfTestParameter 2 | { 3 | [cmdletBinding()] 4 | param ( 5 | [string] $p_string, 6 | [int] $p_int, 7 | [decimal] $p_dec, 8 | [datetime] $p_date, 9 | [bool] $p_bool, 10 | [array] $p_array, 11 | [hashtable] $p_hash 12 | ) 13 | 14 | # Test the string... 15 | Switch ($p_string) 16 | { 17 | $null { "String is null" } 18 | "" { "String is empty" } 19 | default { "String has a value: $p_string" } 20 | } 21 | 22 | Switch ($p_int) 23 | { 24 | $null { "Int is null" } 25 | 0 { "Int is zero" } 26 | default { "Int has a value: $p_int" } 27 | } 28 | 29 | Switch ($p_dec) 30 | { 31 | $null { "Decimal is null" } 32 | 0 { "Decimal is zero" } 33 | default { "Decimal has a value: $p_dec" } 34 | } 35 | 36 | Switch ($p_date) 37 | { 38 | $null { "Date is null" } 39 | 0 { "Date is zero" } 40 | default { "Date has a value: $p_date" } 41 | } 42 | 43 | Switch ($p_bool) 44 | { 45 | $null { "Boolean is null" } 46 | $true { "Boolean is True" } 47 | $false { "Boolean is False" } 48 | default { "Boolean has a value: $p_bool" } 49 | } 50 | 51 | Switch ($p_array) 52 | { 53 | $null { "Array is null" } 54 | default { "Array has a value: $p_array" } 55 | } 56 | 57 | 58 | Switch ($p_hash) 59 | { 60 | $null { "Hashtable is null" } 61 | default { "Hashtable has a value: $p_hash" } 62 | } 63 | 64 | } 65 | 66 | Invoke-UdfTestParameter -------------------------------------------------------------------------------- /PPSFDD/Listings/Chapter03/listing-3-3.ps1: -------------------------------------------------------------------------------- 1 | function New-UdfStateObject 2 | { 3 | [CmdletBinding()] 4 | param ( 5 | [ref]$stateobject 6 | ) 7 | 8 | $instates = Import-CSV -PATH ` 9 | (($env:HOMEDRIVE + $env:HOMEPATH + "\Documents\") + "state_table.csv") 10 | 11 | # Properties... 12 | 13 | $stateobject.value | Add-Member -MemberType noteproperty ` 14 | -Name statedata ` 15 | -Value $instates ` 16 | -Passthru 17 | 18 | [hashtable] $stateht = @{} 19 | foreach ($item in $instates) {$stateht[$item.abbreviation] = $item.name} 20 | 21 | $stateobject.value | Add-Member -MemberType noteproperty ` 22 | -Name Code ` 23 | -Value $stateht ` 24 | -Passthru 25 | 26 | [hashtable] $statenameht = @{} 27 | foreach ($item in $instates) {$statenameht[$item.name] = $item.abbreviation} 28 | 29 | $stateobject.value | Add-Member -MemberType noteproperty ` 30 | -Name Name ` 31 | -Value $statenameht ` 32 | -Passthru 33 | 34 | # Methods... 35 | 36 | $bshowdata = @' 37 | 38 | $this.statedata | Out-GridView 39 | 40 | '@ 41 | 42 | $sshowdata = [scriptblock]::create($bshowdata) 43 | 44 | $stateobject.value | Add-Member -MemberType scriptmethod ` 45 | -Name Show ` 46 | -Value $sshowdata ` 47 | -Passthru 48 | } 49 | 50 | [psobject] $states1 = New-Object psobject 51 | New-UdfStateObject ([ref]$states1) 52 | 53 | $states1.Code["RI"] 54 | 55 | $states1.Name["Vermont"] 56 | 57 | # Line below will displays states in a grid. 58 | # $states1.Show() 59 | -------------------------------------------------------------------------------- /PPSFDD/Listings/Chapter05/listing-5-24.ps1: -------------------------------------------------------------------------------- 1 | function Invoke-UdfFileAction { 2 | [cmdletBinding(SupportsShouldProcess=$true)] 3 | param ( 4 | [Parameter(Mandatory = $true, Position = 0, ParameterSetName = "delete")] 5 | [switch]$dodelete, 6 | [Parameter(Mandatory = $true, Position = 1, ParameterSetName = "delete")] 7 | [string]$filetodelete, 8 | [Parameter(Mandatory = $true, Position = 0, ParameterSetName = "copy")] 9 | [switch]$docopy, 10 | [Parameter(Mandatory = $true, 11 | ValueFromPipelineByPropertyName=$True, ParameterSetName = "copy")] 12 | [string[]]$fullname, 13 | [Parameter(Mandatory = $true, 14 | ValueFromPipelineByPropertyName=$True, ParameterSetName = "copy")] 15 | [long[]]$length, 16 | [Parameter(Mandatory = $true, Position = 1, ParameterSetName = "copy")] 17 | [string]$destpath 18 | ) 19 | 20 | Begin 21 | { 22 | if ($dodelete) 23 | { 24 | try 25 | { 26 | Remove-Item $filetodelete -ErrorAction Stop 27 | write-host "Deleted $filetodelete ." 28 | } 29 | catch 30 | { 31 | "Error: Problem deleting old file." 32 | } 33 | } 34 | } 35 | 36 | Process 37 | { 38 | if ($docopy) 39 | { 40 | try 41 | { 42 | foreach ($filename in $fullname) 43 | { 44 | Copy-Item $filename $destpath -ErrorAction Stop 45 | write-host "File $filename with length of $length copied to $destpath." 46 | } 47 | } 48 | catch 49 | { 50 | "Error: Problem copying file." 51 | } 52 | } 53 | } 54 | } 55 | 56 | # Let's see would happen without actually doing anything. 57 | "somestuff" > somedata.txt 58 | 59 | Invoke-UdfFileAction -dodelete 'somedata.txt' -whatif 60 | 61 | Get-ChildItem *.txt | Invoke-UdfFileAction -docopy 'c:\users\BryanCafferky\hold\' -WhatIf 62 | -------------------------------------------------------------------------------- /PPSFDD/Listings/Chapter12/listing-12-1.ps1: -------------------------------------------------------------------------------- 1 | function Show-UdfJobConsole 2 | { 3 | [CmdletBinding()] 4 | param ( 5 | [string]$jobnamefilter 6 | ) 7 | 8 | function ufn_ShowMessageBox 9 | { 10 | [CmdletBinding()] 11 | param ( 12 | [Parameter(Mandatory=$true,ValueFromPipeline=$false)] 13 | [string] $message, 14 | [Parameter(Mandatory=$true,ValueFromPipeline=$false)] 15 | [string] $title, 16 | [Parameter(Mandatory=$true,ValueFromPipeline=$false)] 17 | [ValidateRange(0,5)] 18 | [int] $type 19 | ) 20 | 21 | RETURN [System.Windows.Forms.MessageBox]::Show($message , $title, $type) 22 | 23 | } 24 | 25 | $actions = "Show Output", "Stop", "Remove", "Resume", "Clear History" 26 | 27 | while ($true) 28 | { 29 | $joblist = Get-Job -Name $jobnamefilter | 30 | Out-GridView -Title "PowerShell Job Console" -OutputMode Multiple 31 | 32 | if ($joblist.count -gt 0) 33 | { 34 | $selection = $actions | Out-GridView -Title "Select Action" -OutputMode Single 35 | foreach ($job in $joblist) 36 | { 37 | switch ($selection) 38 | { 39 | "Show Output" 40 | { 41 | $joboutput = Receive-Job -ID $job.ID -Keep -Verbose 4>&1 42 | If ($joboutput -eq $null) 43 | { 44 | ufn_ShowMessageBox -message "No output to display" -title 'Error' -type 0 45 | } 46 | $joboutput | Out-GridView -Title 'Job Output - Close window to return to the job list' -Wait 47 | } 48 | "Cancel" 49 | { 50 | $job | Stop-Job 51 | } 52 | "Remove" 53 | { 54 | $job | Remove-Job 55 | } 56 | "Resume" 57 | { 58 | $job | Resume-Job 59 | } 60 | } 61 | } 62 | } 63 | else 64 | { 65 | Break; 66 | } 67 | } 68 | 69 | } 70 | 71 | <# Example call... #> 72 | Show-UdfJobConsole '*' 73 | 74 | 75 | -------------------------------------------------------------------------------- /PPSFDD/Listings/Chapter07/listing-7-6.ps1: -------------------------------------------------------------------------------- 1 | Import-Module umd_database 2 | 3 | $SqlConnection = New-Object System.Data.SqlClient.SqlConnection 4 | $SqlConnection.ConnectionString = "Data Source=(local);Integrated Security=SSPI;Initial Catalog=AdventureWorks" 5 | $SqlCmd = New-Object System.Data.SqlClient.SqlCommand 6 | $SqlCmd.CommandText = "[HumanResources].[uspUpdateEmployeePersonalInfoPS]" 7 | $SqlCmd.Connection = $SqlConnection 8 | $SqlCmd.CommandType = [System.Data.CommandType]'StoredProcedure' 9 | $SqlCmd.Parameters.AddWithValue("@BusinessEntityID", 1) >> $null 10 | $SqlCmd.Parameters.AddWithValue("@NationalIDNumber", 295847284) >> $null 11 | $SqlCmd.Parameters.AddWithValue("@BirthDate", '1964-02-02') >> $null 12 | $SqlCmd.Parameters.AddWithValue("@MaritalStatus", 'S') >> $null 13 | $SqlCmd.Parameters.AddWithValue("@Gender", 'M') >> $null 14 | 15 | # -- Output Parameters --- 16 | # JobTitle 17 | $outParameter1 = new-object System.Data.SqlClient.SqlParameter 18 | $outParameter1.ParameterName = "@JobTitle" 19 | $outParameter1.Direction = [System.Data.ParameterDirection]::Output 20 | $outParameter1.DbType = [System.Data.DbType]'string' 21 | $outParameter1.Size = 50 22 | $SqlCmd.Parameters.Add($outParameter1) >> $null 23 | 24 | # HireDate 25 | $outParameter2 = new-object System.Data.SqlClient.SqlParameter 26 | $outParameter2.ParameterName = "@HireDate" 27 | $outParameter2.Direction = [System.Data.ParameterDirection]::Output 28 | $outParameter2.DbType = [System.Data.DbType]'date' 29 | $SqlCmd.Parameters.Add($outParameter2) >> $null 30 | 31 | # VacationHours 32 | $outParameter3 = new-object System.Data.SqlClient.SqlParameter 33 | $outParameter3.ParameterName = "@VacationHours" 34 | $outParameter3.Direction = [System.Data.ParameterDirection]::Output 35 | $outParameter3.DbType = [System.Data.DbType]'int16' 36 | $SqlCmd.Parameters.Add($outParameter3) >> $null 37 | 38 | $SqlConnection.Open() 39 | $result = $SqlCmd.ExecuteNonQuery() 40 | $SqlConnection.Close() 41 | 42 | $SqlCmd.Parameters["@jobtitle"].value 43 | $SqlCmd.Parameters["@hiredate"].value 44 | $SqlCmd.Parameters["@VacationHours"].value 45 | -------------------------------------------------------------------------------- /PPSFDD/Data/test.txt: -------------------------------------------------------------------------------- 1 | this is a line of a file. 2 | this is a line of a file. 3 | this is a line of a file. 4 | this is a line of a file. 5 | this is a line of a file. 6 | this is a line of a file. 7 | this is a line of a file. 8 | this is a line of a file. 9 | this is a line of a file. 10 | this is a line of a file. 11 | this is a line of a file. 12 | this is a line of a file. 13 | this is a line of a file. 14 | this is a line of a file. 15 | this is a line of a file. 16 | this is a line of a file. 17 | this is a line of a file. 18 | this is a line of a file. 19 | this is a line of a file. 20 | this is a line of a file. 21 | this is a line of a file. 22 | this is a line of a file. 23 | this is a line of a file. 24 | this is a line of a file. 25 | this is a line of a file. 26 | this is a line of a file. 27 | this is a line of a file. 28 | this is a line of a file. 29 | this is a line of a file. 30 | this is a line of a file. 31 | this is a line of a file. 32 | this is a line of a file. 33 | this is a line of a file. 34 | this is a line of a file. 35 | this is a line of a file. 36 | this is a line of a file. 37 | this is a line of a file. 38 | this is a line of a file. 39 | this is a line of a file. 40 | this is a line of a file. 41 | this is a line of a file. 42 | this is a line of a file. 43 | this is a line of a file. 44 | this is a line of a file. 45 | this is a line of a file. 46 | this is a line of a file. 47 | this is a line of a file. 48 | this is a line of a file. 49 | this is a line of a file. 50 | this is a line of a file. 51 | this is a line of a file. 52 | this is a line of a file. 53 | this is a line of a file. 54 | this is a line of a file. 55 | this is a line of a file. 56 | this is a line of a file. 57 | this is a line of a file. 58 | this is a line of a file. 59 | this is a line of a file. 60 | this is a line of a file. 61 | this is a line of a file. 62 | this is a line of a file. 63 | this is a line of a file. 64 | this is a line of a file. 65 | this is a line of a file. 66 | this is a line of a file. 67 | this is a line of a file. 68 | this is a line of a file. 69 | this is a line of a file. 70 | this is a line of a file. -------------------------------------------------------------------------------- /PPSFDD/Data/somedata.txt: -------------------------------------------------------------------------------- 1 | this is a line of a file. 2 | this is a line of a file. 3 | this is a line of a file. 4 | this is a line of a file. 5 | this is a line of a file. 6 | this is a line of a file. 7 | this is a line of a file. 8 | this is a line of a file. 9 | this is a line of a file. 10 | this is a line of a file. 11 | this is a line of a file. 12 | this is a line of a file. 13 | this is a line of a file. 14 | this is a line of a file. 15 | this is a line of a file. 16 | this is a line of a file. 17 | this is a line of a file. 18 | this is a line of a file. 19 | this is a line of a file. 20 | this is a line of a file. 21 | this is a line of a file. 22 | this is a line of a file. 23 | this is a line of a file. 24 | this is a line of a file. 25 | this is a line of a file. 26 | this is a line of a file. 27 | this is a line of a file. 28 | this is a line of a file. 29 | this is a line of a file. 30 | this is a line of a file. 31 | this is a line of a file. 32 | this is a line of a file. 33 | this is a line of a file. 34 | this is a line of a file. 35 | this is a line of a file. 36 | this is a line of a file. 37 | this is a line of a file. 38 | this is a line of a file. 39 | this is a line of a file. 40 | this is a line of a file. 41 | this is a line of a file. 42 | this is a line of a file. 43 | this is a line of a file. 44 | this is a line of a file. 45 | this is a line of a file. 46 | this is a line of a file. 47 | this is a line of a file. 48 | this is a line of a file. 49 | this is a line of a file. 50 | this is a line of a file. 51 | this is a line of a file. 52 | this is a line of a file. 53 | this is a line of a file. 54 | this is a line of a file. 55 | this is a line of a file. 56 | this is a line of a file. 57 | this is a line of a file. 58 | this is a line of a file. 59 | this is a line of a file. 60 | this is a line of a file. 61 | this is a line of a file. 62 | this is a line of a file. 63 | this is a line of a file. 64 | this is a line of a file. 65 | this is a line of a file. 66 | this is a line of a file. 67 | this is a line of a file. 68 | this is a line of a file. 69 | this is a line of a file. 70 | this is a line of a file. -------------------------------------------------------------------------------- /PPSFDD/Listings/Chapter04/listing-4-11.ps1: -------------------------------------------------------------------------------- 1 | # Note: This form code was originally generated by AdminScriptEditor 4.0 2 | # available for free at http://www.itninja.com/community/admin-script-editor 3 | 4 | # First, let's define our windows form objects... 5 | 6 | [void][System.Reflection.Assembly]::LoadWithPartialName("System.Windows.Forms") 7 | [void][System.Reflection.Assembly]::LoadWithPartialName("System.Drawing") 8 | 9 | #~~< Form1 >~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 10 | $Form1 = New-Object System.Windows.Forms.Form 11 | $Form1.ClientSize = New-Object System.Drawing.Size(167, 148) 12 | $Form1.Text = "Form1" 13 | #~~< Label1 >~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 14 | $Label1 = New-Object System.Windows.Forms.Label 15 | $Label1.Location = New-Object System.Drawing.Point(41, 50) 16 | $Label1.Size = New-Object System.Drawing.Size(100, 23) 17 | $Label1.TabIndex = 1 18 | $Label1.Text = "Start" 19 | #~~< Button1 >~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 20 | $Button1 = New-Object System.Windows.Forms.Button 21 | $Button1.Location = New-Object System.Drawing.Point(41, 87) 22 | $Button1.Size = New-Object System.Drawing.Size(75, 23) 23 | $Button1.TabIndex = 0 24 | $Button1.Text = "Button1" 25 | $Button1.UseVisualStyleBackColor = $true 26 | 27 | # Second, add the controls to the form... 28 | $Form1.Controls.Add($Label1) # Add the label to the form. 29 | $Form1.Controls.Add($Button1) # Add the button to the form. 30 | 31 | # Third the function to handle the button click... 32 | function DaButtonWasClicked( $object ){ 33 | $Label1.Text = "Button Clicked"; 34 | } 35 | 36 | # Fourth, hook up the button click event to the function that will execute... 37 | $Button1.add_Click({DaButtonWasClicked($Button1)}) 38 | 39 | # Fifth, declare the function to open the form and start the event trapping... 40 | function Main{ 41 | [System.Windows.Forms.Application]::EnableVisualStyles() 42 | [System.Windows.Forms.Application]::Run($Form1) 43 | } 44 | 45 | # Finally, call the function Main to open the windows form... 46 | Main # This call must remain below all other event functions 47 | -------------------------------------------------------------------------------- /PPSFDD/Data/Employees.txt: -------------------------------------------------------------------------------- 1 | "ID","Company","Last Name","First Name","E-mail Address","Job Title","Business Phone","Home Phone","Mobile Phone","Fax Number","Address","City","State/Province","ZIP/Postal Code","Country/Region","Web Page","Notes","Attachments" 2 | 1,"Northwind Traders","Freehafer","Nancy","nancy@northwindtraders.com","Sales Representative","(123)555-0100","(123)555-0102",,"(123)555-0103","123 1st Avenue","Seattle","WA","99999","USA","#http://northwindtraders.com#",, 3 | 2,"Northwind Traders","Cencini","Andrew","andrew@northwindtraders.com","Vice President, Sales","(123)555-0100","(123)555-0102",,"(123)555-0103","123 2nd Avenue","Bellevue","WA","99999","USA","http://northwindtraders.com#http://northwindtraders.com/#","Joined the company as a sales representative, was promoted to sales manager and was then named vice president of sales.", 4 | 3,"Northwind Traders","Kotas","Jan","jan@northwindtraders.com","Sales Representative","(123)555-0100","(123)555-0102",,"(123)555-0103","123 3rd Avenue","Redmond","WA","99999","USA","http://northwindtraders.com#http://northwindtraders.com/#","Was hired as a sales associate and was promoted to sales representative.", 5 | 4,"Northwind Traders","Sergienko","Mariya","mariya@northwindtraders.com","Sales Representative","(123)555-0100","(123)555-0102",,"(123)555-0103","123 4th Avenue","Kirkland","WA","99999","USA","http://northwindtraders.com#http://northwindtraders.com/#",, 6 | 5,"Northwind Traders","Thorpe","Steven","steven@northwindtraders.com","Sales Manager","(123)555-0100","(123)555-0102",,"(123)555-0103","123 5th Avenue","Seattle","WA","99999","USA","http://northwindtraders.com#http://northwindtraders.com/#","Joined the company as a sales representative and was promoted to sales manager. Fluent in French.", 7 | 6,"Northwind Traders","Neipper","Michael","michael@northwindtraders.com","Sales Representative","(123)555-0100","(123)555-0102",,"(123)555-0103","123 6th Avenue","Redmond","WA","99999","USA","http://northwindtraders.com#http://northwindtraders.com/#","Fluent in Japanese and can read and write French, Portuguese, and Spanish.", 8 | 7,"Northwind Traders","Zare","Robert","robert@northwindtraders.com","Sales Representative","(123)555-0100","(123)555-0102",,"(123)555-0103","123 7th Avenue","Seattle","WA","99999","USA","http://northwindtraders.com#http://northwindtraders.com/#",, 9 | 8,"Northwind Traders","Giussani","Laura","laura@northwindtraders.com","Sales Coordinator","(123)555-0100","(123)555-0102",,"(123)555-0103","123 8th Avenue","Redmond","WA","99999","USA","http://northwindtraders.com#http://northwindtraders.com/#","Reads and writes French.", 10 | 9,"Northwind Traders","Hellung-Larsen","Anne","anne@northwindtraders.com","Sales Representative","(123)555-0100","(123)555-0102",,"(123)555-0103","123 9th Avenue","Seattle","WA","99999","USA","http://northwindtraders.com#http://northwindtraders.com/#","Fluent in French and German.", 11 | -------------------------------------------------------------------------------- /PPSFDD/ReadMe.txt: -------------------------------------------------------------------------------- 1 | Readme 2 | 3 | Code listings from the book are in the folder named Listings under the appropriate Chapter for the folder. The listing names match the listing id from the look, i.e. listing-2-1 would be the first listing in Chapter 2. 4 | 5 | Script modules are in the folder named Modules with each module in its own folder. Each module folder should be copied to \WindowsPowerShell\Modules under the user's Documents folder. Each module must be in a folder of the same name as the module. 6 | 7 | Data files are in the folder named Data. For the most part these should be copied to the user's Documents folder except as noted below. 8 | 9 | 10 | Notes 11 | 12 | - All data files are for demonstration purposes only and should not be relied on for accuracy. 13 | 14 | - Chapter 3 listing 3-8 will produce an error if script.sql is in the Documents folder. It is needed to run a subsequent script so I recommend ignoring the error. 15 | 16 | - Chapter 5 - For convenience, the listings for language translations, listings-5-25 through listing-5-30, are cosolidated into the folder \translate in that chapter's Listings folder. All the languge folders with their string translation files are under the translate folder so you can just execute the translate script in the translate folder. 17 | 18 | - Chapter 6 -There are two versions of module umd_simple. The first is named umd_simple and does not include the Export_ModuleMember cmdlet so everything is exported matching the first example of umd_simple in chapter 6. Later, the chapter covers using the Export-ModuleMember cmdlet so a different version named umd_simple_withexport is provided that matches the code in the chapter that discusses exporting module members. 19 | 20 | Chapter 9 - The notes below are for Listing 9 - 1 - ETL Load Script. 21 | 22 | When you run the script that polls for the data file, it looks in the sub folder \FTP under the user's Documents folder. After you run the script, copy the file there and the load script will copy/move the file to other folders as it is processed. Note: \Inbound, \Unzipped, \Process, and \Archive folders must already be created under the user's Documents folder. 23 | 24 | The test file provided is sales_abccompany_20141015.zip. Put it in FTP folder when you are ready to test the script. 25 | 26 | The ETL script polls for file pattern sales_*.zip in \Documents\FTP\ 27 | 28 | Where is is moved to the folders below for each step of processing... 29 | 30 | Documents\Inbound\ 31 | Documents\unzipped\ 32 | Documents\Process\ 33 | Documents\Archive\ 34 | 35 | In summary, overall ETL script run the script and then copy sales_abccompany_20141015.zip to \Documents\FTP\. 36 | 37 | 38 | Chapter 10 39 | 40 | The file psappconfig.csv must be saved to c:\pasappconfig\psappconfig.csv. 41 | The file psappconfig.txt must be saved to c:\pasappconfig\psappconfig.txt 42 | 43 | Note: psappconfig.txt is also in the module folder umd_psappconfig for use by that module. 44 | 45 | Chapter 12 - umd_jobs - Is not mentioned in book but incorporates listings 12-1 and 12-2. 46 | 47 | 48 | 49 | 50 | 51 | 52 | -------------------------------------------------------------------------------- /PPSFDD/Listings/Chapter03/listing-3-4.ps1: -------------------------------------------------------------------------------- 1 | function New-UdfGeoObject () 2 | { 3 | [CmdletBinding()] 4 | param ( 5 | [ref]$geoobject 6 | ) 7 | 8 | # Check if the SQL module is loaded and if not, load it. 9 | if(-not(Get-Module -name "sqlps")) 10 | { 11 | Import-Module "sqlps" 12 | } 13 | 14 | set-location SQLSERVER:\SQL\BryanCafferkyPC\DEFAULT\Databases\Adventureworks\Tables 15 | 16 | # Load Territory 17 | 18 | $territoryrs = Invoke-Sqlcmd -Query "SELECT distinct [Name],[CountryRegionCode] FROM [AdventureWorks].[Sales].[SalesTerritory];" -QueryTimeout 3 19 | 20 | $territoryhash = @{} 21 | foreach ($item in $territoryrs) {$territoryhash[$item.Name] = $item.CountryRegionCode} 22 | 23 | $geoobject.value | Add-Member -MemberType noteproperty ` 24 | -Name Territory ` 25 | -Value $territoryhash 26 | 27 | # Load Currency 28 | 29 | $currencyrs = Invoke-Sqlcmd -Query "SELECT [CurrencyCode], [Name] FROM [AdventureWorks].[Sales].[Currency];" -QueryTimeout 3 30 | 31 | $currencyhash = @{} 32 | foreach ($item in $currencyrs) {$currencyhash[$item.CurrencyCode] = $item.Name} 33 | 34 | 35 | $geoobject.value | Add-Member -MemberType noteproperty ` 36 | -Name Currency ` 37 | -Value $currencyhash 38 | 39 | # Load CurrencyConversion 40 | 41 | $sql = "SELECT [FromCurrencyCode], [ToCurrencyCode],[AverageRate], [EndOfDayRate],cast([CurrencyRateDate] as date) as CurrencyRateDate 42 | FROM [AdventureWorks].[Sales].[CurrencyRate] 43 | where [CurrencyRateDate] = (select max([CurrencyRateDate]) from [AdventureWorks].[Sales].[CurrencyRate]);" 44 | 45 | $convrate = @{} 46 | 47 | $convrate = Invoke-Sqlcmd -Query $sql -QueryTimeout 3 48 | 49 | $geoobject.value | Add-Member -MemberType noteproperty ` 50 | -Name CurrencyConversion ` 51 | -Value $convrate 52 | 53 | # Define Methods... 54 | 55 | # Territory - Look Up Country 56 | 57 | $bterritorytocountry = @' 58 | param([string] $territory) 59 | 60 | RETURN $this.Territory["$territory"] 61 | '@ 62 | 63 | $sterritorytocountry = [scriptblock]::create($bterritorytocountry) 64 | 65 | $geoobject.value | Add-Member -MemberType scriptmethod ` 66 | -Name GetCountryForTerritory ` 67 | -Value $sterritorytocountry ` 68 | -Passthru 69 | 70 | $convertcurrency = @' 71 | param([string] $targetcurrency,[decimal] $amount) 72 | 73 | $row = $this.CurrencyConversion | where-object {$_["ToCurrencyCode"] -eq "$targetcurrency" } 74 | $result = $row["AverageRate"] * $amount 75 | RETURN $result 76 | '@ 77 | 78 | $sconvertcurrency = [scriptblock]::create($convertcurrency) 79 | 80 | $geoobject.value | Add-Member -MemberType scriptmethod ` 81 | -Name ConvertCurrency ` 82 | -Value $sconvertcurrency ` 83 | -Passthru 84 | } 85 | -------------------------------------------------------------------------------- /PPSFDD/Modules/umd_state/umd_state.psm1: -------------------------------------------------------------------------------- 1 | <# Module Name: umd_state.psm1 2 | 3 | Author: Bryan Cafferky 4 | 5 | Purpose: A module demostration. 6 | 7 | #> 8 | <# 9 | .SYNOPSIS 10 | Demonstrate the creation and use of a custom module written in PowerShell. 11 | 12 | .Description 13 | This module was created to demonstrate the use of custom PowerShell modules. 14 | 15 | .Notes 16 | Author: Bryan Cafferky for Pro PowerShell Development. 17 | Version: 1.0 18 | 19 | #> 20 | 21 | [string]$script:salestaxfilepath = ($env:HomeDrive + $env:HOMEPATH + "\Documents\StateSalesTaxRates.csv”) 22 | 23 | $inexchangerate = Import-CSV ($env:HomeDrive + $env:HOMEPATH + "\Documents\currencyexchangerate.csv") 24 | 25 | [hashtable]$script:salestax = @{} 26 | 27 | function Set-UdfSalesTaxFilepath { 28 | [CmdletBinding()] 29 | param ( 30 | [Parameter(Mandatory = $true)] 31 | [ValidateScript({ Test-Path $_ })] 32 | [string]$p_taxfilepath 33 | ) 34 | } 35 | { 36 | $script:salestaxfilepath = $p_taxfilepath 37 | } 38 | 39 | function Get-UdfSalesTaxFilepath 40 | { 41 | Write-Host $script:salestaxfilepath 42 | } 43 | 44 | 45 | function Invoke-UdfStateRateLoad 46 | { 47 | 48 | $insalestax = Import-CSV $salestaxfilepath 49 | 50 | foreach ($item in $insalestax) {$script:salestax[$item.StateCode] = $item.SalesTaxRate} 51 | 52 | } 53 | 54 | function Get-UdfStateTaxRate 55 | { 56 | [CmdletBinding()] 57 | param ( 58 | [string] $p_statecode 59 | ) 60 | 61 | if ($script:salestax.Count -eq 0) 62 | { 63 | "Here" 64 | Invoke-UdfStateRateLoad 65 | } 66 | 67 | $script:salestax["$p_statecode"] 68 | 69 | } 70 | 71 | # Note: Site: http://www.xe.com/currency/usd-us-dollar?r= provided Currency Conversion values. 72 | 73 | $exchangerate = Import-CSV ($env:HomeDrive + $env:HOMEPATH + "\Documents\currencyexchangerate.csv") 74 | 75 | function Get-UdfExchangeRate 76 | { 77 | [CmdletBinding()] 78 | param ( 79 | [Parameter(Mandatory = $true, Position = 0)] 80 | [string] $p_currencycd, 81 | [Parameter(Mandatory = $true, Position = 1)] 82 | [string] $p_asofdate, 83 | [Parameter(Mandatory = $true, Position = 2, ParameterSetName = "unitsperusd")] 84 | [switch] $UnitsPerUSD, 85 | [Parameter(Mandatory = $true, Position = 2, ParameterSetName = "usdperunits")] 86 | [switch] $USDPerUnits, 87 | [Parameter(Mandatory = $true, Position = 2, ParameterSetName = "currencyname")] 88 | [switch] $CurrencyName 89 | ) 90 | 91 | foreach ($item in $exchangerate) 92 | { 93 | if ($item.CurrencyCD -eq $p_currencycd -and $item.AsOfDate -eq $p_asofdate) 94 | { 95 | if ($CurrencyName) { Return $item.CurrencyName } 96 | if ($UnitsPerUSD) { Return $item.UnitsPerUSD } 97 | if ($USDPerUnits) { Return $item.USDPerUnit } 98 | } 99 | 100 | } 101 | } 102 | -------------------------------------------------------------------------------- /PPSFDD/Modules/umd_jobs/umd_jobs.psm1: -------------------------------------------------------------------------------- 1 | function Show-UdfJobConsole 2 | { 3 | [CmdletBinding()] 4 | param ( 5 | [string]$jobnamefilter 6 | ) 7 | 8 | function ufn_ShowMessageBox 9 | { 10 | [CmdletBinding()] 11 | param ( 12 | [Parameter(Mandatory=$true,ValueFromPipeline=$false)] 13 | [string] $message, 14 | [Parameter(Mandatory=$true,ValueFromPipeline=$false)] 15 | [string] $title, 16 | [Parameter(Mandatory=$true,ValueFromPipeline=$false)] 17 | [ValidateRange(0,5)] 18 | [int] $type 19 | ) 20 | 21 | RETURN [System.Windows.Forms.MessageBox]::Show($message , $title, $type) 22 | 23 | } 24 | 25 | $actions = "Show Output", "Stop", "Remove", "Resume", "Clear History" 26 | 27 | while ($true) 28 | { 29 | $joblist = Get-Job -Name $jobnamefilter | 30 | Out-GridView -Title "PowerShell Job Console" -OutputMode Multiple 31 | 32 | if ($joblist.count -gt 0) 33 | { 34 | $selection = $actions | Out-GridView -Title "Select Action" -OutputMode Single 35 | foreach ($job in $joblist) 36 | { 37 | switch ($selection) 38 | { 39 | "Show Output" 40 | { 41 | $joboutput = Receive-Job -ID $job.ID -Keep -Verbose 4>&1 42 | If ($joboutput -eq $null) 43 | { 44 | ufn_ShowMessageBox -message "No output to display" -title 'Error' -type 0 45 | } 46 | $joboutput | Out-GridView -Title 'Job Output - Close window to return to the job list' -Wait 47 | } 48 | "Cancel" 49 | { 50 | $job | Stop-Job 51 | } 52 | "Remove" 53 | { 54 | $job | Remove-Job 55 | } 56 | "Resume" 57 | { 58 | $job | Resume-Job 59 | } 60 | } 61 | } 62 | } 63 | else 64 | { 65 | Break; 66 | } 67 | } 68 | 69 | } 70 | 71 | <# Example call... 72 | Show-UdfJobConsole '*' 73 | #> 74 | 75 | function Invoke-UdfSQLAgentJob 76 | { 77 | 78 | [CmdletBinding()] 79 | param ( 80 | [string]$sqlserverpath, 81 | [string]$jobfilter = '*' 82 | ) 83 | # Import the SQL Server module 84 | if(-not(Get-Module -name "sqlps")) 85 | { 86 | Import-Module "sqlps" -DisableNameChecking 87 | } 88 | 89 | # Set where you are in SQL Server... 90 | set-location $sqlserverpath 91 | 92 | while ($true) 93 | { 94 | 95 | $jobname = $null 96 | 97 | $jobname = Get-ChildItem | 98 | Select-Object -Property Name, Description, LastRunDate, LastRunOutcome | 99 | Where-Object {$_.name -like "$jobfilter*"} | 100 | Out-GridView -Title "Select a Job to Run" -OutputMode Single 101 | 102 | If (!$jobname) { Break } 103 | 104 | $jobobject = Get-ChildItem | where-object {$_.name -eq $jobname.Name} 105 | 106 | $jobobject.start() 107 | 108 | } 109 | 110 | } 111 | <# Example call... 112 | Invoke-UdfSQLAgentJob -sqlserverpath 'SQLSERVER:\SQL\BryanCafferkyPC\DEFAULT\JobServer\Jobs\' 113 | #> -------------------------------------------------------------------------------- /PPSFDD/Modules/umd_database/scr_load_products.ps1: -------------------------------------------------------------------------------- 1 | cls 2 | # Good flat file blog... 3 | # https://www.simple-talk.com/sysadmin/powershell/powershell-data-basics-file-based-data/ 4 | 5 | # Pass Ref with other parameters... 6 | # http://geekswithblogs.net/Lance/archive/2009/01/14/pass-by-reference-parameters-in-powershell.aspx 7 | 8 | ufn_get_sqldml $mappingset -dmloperation Insert "dbo.Products" 9 | ufn_get_sqldml $mappingset -dmloperation Merge "dbo.Products" 10 | ufn_get_sqldml $mappingset -dmloperation Delete "dbo.Products" 11 | 12 | # ufn_get_incolumnlist $mapping 13 | 14 | Import-Module umd_database 15 | 16 | Import-Module umd_etl_functions 17 | 18 | function ufn_process_products_transformations 19 | { 20 | [CmdletBinding()] 21 | param ( 22 | [Parameter(ValueFromPipeline=$True)]$mypipe = "default" 23 | ) 24 | process 25 | { 26 | $mypipe | Add-Member -MemberType NoteProperty -Name "NewName" -Value "Test" 27 | 28 | if ($mypipe."Minimum Reorder Quantity" -eq [DBNull]::Value) { $mypipe."Minimum Reorder Quantity" = 0 } 29 | 30 | Return $mypipe 31 | } 32 | } 33 | 34 | 35 | 36 | <# Define the mapping... #> 37 | $mappingset = @() # Create a collection object. 38 | $mappingset += (ufn_add_mapping "[Supplier IDs]" "SupplierIDs" "'" $false) 39 | $mappingset += (ufn_add_mapping "[ID]" "ID" "" $true) 40 | $mappingset += (ufn_add_mapping "[Product Code]" "ProductCode" "'" $false) 41 | $mappingset += (ufn_add_mapping "[Product Name]" "ProductName" "'" $false) 42 | $mappingset += (ufn_add_mapping "[Description]" "Description" "'" $false) 43 | $mappingset += (ufn_add_mapping "[Standard Cost]" "StandardCost" "" $false) 44 | $mappingset += (ufn_add_mapping "[Reorder Level]" "ReorderLevel" "" $false) 45 | $mappingset += (ufn_add_mapping "[Target Level]" "TargetLevel" "" $false) 46 | $mappingset += (ufn_add_mapping "[List Price]" "ListPrice" "" $false) 47 | $mappingset += (ufn_add_mapping "[Quantity Per Unit]" "QuantityPerUnit" "'" $false) 48 | $mappingset += (ufn_add_mapping "[Discontinued]" "Discontinued" "'" $false) 49 | $mappingset += (ufn_add_mapping "[Minimum Reorder Quantity]" "MinimumReorderQuantity" "" $false) 50 | $mappingset += (ufn_add_mapping "[Category]" "Category" "'" $false) 51 | $mappingset += (ufn_add_mapping "[Attachments]" "Attachments" "'" $false) 52 | 53 | $mappingset 54 | 55 | 56 | <# Define the SQL Server Target #> 57 | Import-Module umd_database 58 | 59 | [psobject] $SqlServer1 = New-Object psobject 60 | ufn_create_connection ([ref]$SqlServer1) 61 | 62 | $SqlServer1.ConnectionType = 'ADO' 63 | $SqlServer1.DatabaseType = 'SqlServer' 64 | $SqlServer1.Server = '(local)' 65 | $SqlServer1.DatabaseName = 'Development' 66 | $SqlServer1.UseCredential = 'N' 67 | $SqlServer1.SetAuthenticationType('Integrated') 68 | 69 | $SqlServer1.BuildConnectionString() 70 | $SqlServer1.ConnectionString 71 | 72 | $SqlServer1.RunSQL("select * from [dbo].[Products]", $true) 73 | 74 | <# Define the MS Access Connection - Caution: 32 bit ISE only #> 75 | $global:referencepath = $env:HomeDrive + $env:HOMEPATH + "\Documents\" 76 | 77 | [psobject] $access1 = New-Object psobject 78 | ufn_create_connection ([ref]$access1) 79 | $access1.ConnectionType = 'ODBC' 80 | $access1.DatabaseType = 'Access' 81 | $access1.DatabaseName = ($global:referencepath + 'DesktopNorthwind2007.accdb') 82 | $access1.UseCredential = 'N' 83 | $access1.SetAuthenticationType('DSNLess') 84 | $access1.Driver = "Microsoft Access Driver (*.mdb, *.accdb)" 85 | $access1.BuildConnectionString() 86 | $access1.ConnectionString 87 | 88 | $access1.RunSQL("select * from Products", $true) 89 | 90 | <# SQL Server Destination... #> 91 | [psobject] $SqlServer1 = New-Object psobject 92 | ufn_create_connection ([ref]$SqlServer1) 93 | 94 | 95 | cls 96 | # $SqlServer1.RunSQL("truncate table [dbo].Products", $false) ; 97 | $access1.RunSQL("select * from Products order by id", $true) | ufn_process_products_transformations ` 98 | | ufn_process_sqldml -Mapping $mappingset -DmlOperation "Merge" -Destinationtablename "[dbo].Products" -connection $SqlServer1 -Verbose 99 | 100 | # Delete... 101 | cls 102 | $access1.RunSQL("select * from Products order by id", $true) | ufn_process_transformations ` 103 | | ufn_process_sqldml -Mapping $mappingset -DmlOperation "Delete" -Destinationtablename "[dbo].Products" -connection $SqlServer1 -Verbose 104 | 105 | 106 | $SqlServer1.RunSQL("select * from dbo.Products", $true) | ufn_process_transformations 107 | 108 | cls 109 | $SqlServer1.RunSQL("truncate table dbo.Products", $true) 110 | $myconnection1.RunSQL("select * from Products", $true) | ufn_process_transformations ` 111 | | ufn_process_sqldml -Mapping $mappingset -DmlOperation "Insert" -Destinationtablename "[dbo].Products" -connection $SqlServer1 -Verbose 112 | 113 | # Load Products... 114 | 115 | 116 | 117 | $myconnection1.RunSQL("select top 10 * from Products", $true) | Select-Object -Property 'Target Level' 118 | 119 | $myconnection1.RunSQL("select top 10 * from Products", $true) ` 120 | | ufn_process_sqldml -Mapping $mappingset -DmlOperation "Insert" -Destinationtablename "[dbo].Products" -connection $SqlServer1 -Verbose 121 | 122 | 123 | 124 | 125 | -------------------------------------------------------------------------------- /PPSFDD/Data/state_table.csv: -------------------------------------------------------------------------------- 1 | id,name,abbreviation,country,type,sort,status,occupied,notes,fips_state,assoc_press,standard_federal_region,census_region,census_region_name,census_division,census_division_name,circuit_court 2 | "1","Alabama","AL","USA","state","10","current","occupied","","1","Ala.","IV","3","South","6","East South Central","11" 3 | "2","Alaska","AK","USA","state","10","current","occupied","","2","Alaska","X","4","West","9","Pacific","9" 4 | "3","Arizona","AZ","USA","state","10","current","occupied","","4","Ariz.","IX","4","West","8","Mountain","9" 5 | "4","Arkansas","AR","USA","state","10","current","occupied","","5","Ark.","VI","3","South","7","West South Central","8" 6 | "5","California","CA","USA","state","10","current","occupied","","6","Calif.","IX","4","West","9","Pacific","9" 7 | "6","Colorado","CO","USA","state","10","current","occupied","","8","Colo.","VIII","4","West","8","Mountain","10" 8 | "7","Connecticut","CT","USA","state","10","current","occupied","","9","Conn.","I","1","Northeast","1","New England","2" 9 | "8","Delaware","DE","USA","state","10","current","occupied","","10","Del.","III","3","South","5","South Atlantic","3" 10 | "9","Florida","FL","USA","state","10","current","occupied","","12","Fla.","IV","3","South","5","South Atlantic","11" 11 | "10","Georgia","GA","USA","state","10","current","occupied","","13","Ga.","IV","3","South","5","South Atlantic","11" 12 | "11","Hawaii","HI","USA","state","10","current","occupied","","15","Hawaii","IX","4","West","9","Pacific","9" 13 | "12","Idaho","ID","USA","state","10","current","occupied","","16","Idaho","X","4","West","8","Mountain","9" 14 | "13","Illinois","IL","USA","state","10","current","occupied","","17","Ill.","V","2","Midwest","3","East North Central","7" 15 | "14","Indiana","IN","USA","state","10","current","occupied","","18","Ind.","V","2","Midwest","3","East North Central","7" 16 | "15","Iowa","IA","USA","state","10","current","occupied","","19","Iowa","VII","2","Midwest","4","West North Central","8" 17 | "16","Kansas","KS","USA","state","10","current","occupied","","20","Kan.","VII","2","Midwest","4","West North Central","10" 18 | "17","Kentucky","KY","USA","state","10","current","occupied","","21","Ky.","IV","3","South","6","East South Central","6" 19 | "18","Louisiana","LA","USA","state","10","current","occupied","","22","La.","VI","3","South","7","West South Central","5" 20 | "19","Maine","ME","USA","state","10","current","occupied","","23","Maine","I","1","Northeast","1","New England","1" 21 | "20","Maryland","MD","USA","state","10","current","occupied","","24","Md.","III","3","South","5","South Atlantic","4" 22 | "21","Massachusetts","MA","USA","state","10","current","occupied","","25","Mass.","I","1","Northeast","1","New England","1" 23 | "22","Michigan","MI","USA","state","10","current","occupied","","26","Mich.","V","2","Midwest","3","East North Central","6" 24 | "23","Minnesota","MN","USA","state","10","current","occupied","","27","Minn.","V","2","Midwest","4","West North Central","8" 25 | "24","Mississippi","MS","USA","state","10","current","occupied","","28","Miss.","IV","3","South","6","East South Central","5" 26 | "25","Missouri","MO","USA","state","10","current","occupied","","29","Mo.","VII","2","Midwest","4","West North Central","8" 27 | "26","Montana","MT","USA","state","10","current","occupied","","30","Mont.","VIII","4","West","8","Mountain","9" 28 | "27","Nebraska","NE","USA","state","10","current","occupied","","31","Nebr.","VII","2","Midwest","4","West North Central","8" 29 | "28","Nevada","NV","USA","state","10","current","occupied","","32","Nev.","IX","4","West","8","Mountain","9" 30 | "29","New Hampshire","NH","USA","state","10","current","occupied","","33","N.H.","I","1","Northeast","1","New England","1" 31 | "30","New Jersey","NJ","USA","state","10","current","occupied","","34","N.J.","II","1","Northeast","2","Mid-Atlantic","3" 32 | "31","New Mexico","NM","USA","state","10","current","occupied","","35","N.M.","VI","4","West","8","Mountain","10" 33 | "32","New York","NY","USA","state","10","current","occupied","","36","N.Y.","II","1","Northeast","2","Mid-Atlantic","2" 34 | "33","North Carolina","NC","USA","state","10","current","occupied","","37","N.C.","IV","3","South","5","South Atlantic","4" 35 | "34","North Dakota","ND","USA","state","10","current","occupied","","38","N.D.","VIII","2","Midwest","4","West North Central","8" 36 | "35","Ohio","OH","USA","state","10","current","occupied","","39","Ohio","V","2","Midwest","3","East North Central","6" 37 | "36","Oklahoma","OK","USA","state","10","current","occupied","","40","Okla.","VI","3","South","7","West South Central","10" 38 | "37","Oregon","OR","USA","state","10","current","occupied","","41","Ore.","X","4","West","9","Pacific","9" 39 | "38","Pennsylvania","PA","USA","state","10","current","occupied","","42","Pa.","III","1","Northeast","2","Mid-Atlantic","3" 40 | "39","Rhode Island","RI","USA","state","10","current","occupied","","44","R.I.","I","1","Northeast","1","New England","1" 41 | "40","South Carolina","SC","USA","state","10","current","occupied","","45","S.C.","IV","3","South","5","South Atlantic","4" 42 | "41","South Dakota","SD","USA","state","10","current","occupied","","46","S.D.","VIII","2","Midwest","4","West North Central","8" 43 | "42","Tennessee","TN","USA","state","10","current","occupied","","47","Tenn.","IV","3","South","6","East South Central","6" 44 | "43","Texas","TX","USA","state","10","current","occupied","","48","Texas","VI","3","South","7","West South Central","5" 45 | "44","Utah","UT","USA","state","10","current","occupied","","49","Utah","VIII","4","West","8","Mountain","10" 46 | "45","Vermont","VT","USA","state","10","current","occupied","","50","Vt.","I","1","Northeast","1","New England","2" 47 | "46","Virginia","VA","USA","state","10","current","occupied","","51","Va.","III","3","South","5","South Atlantic","4" 48 | "47","Washington","WA","USA","state","10","current","occupied","","53","Wash.","X","4","West","9","Pacific","9" 49 | "48","West Virginia","WV","USA","state","10","current","occupied","","54","W.Va.","III","3","South","5","South Atlantic","4" 50 | "49","Wisconsin","WI","USA","state","10","current","occupied","","55","Wis.","V","2","Midwest","3","East North Central","7" 51 | "50","Wyoming","WY","USA","state","10","current","occupied","","56","Wyo.","VIII","4","West","8","Mountain","10" 52 | "51","Washington DC","DC","USA","capitol","10","current","occupied","","11","","III","3","South","5","South Atlantic","D.C." 53 | -------------------------------------------------------------------------------- /PPSFDD/Modules/umd_workflow/umd_workflow.psm1: -------------------------------------------------------------------------------- 1 | Import-Module umd_database 2 | Import-module umd_northwind_etl 3 | Import-Module umd_etl_functions 4 | 5 | [psobject] $global:SqlServer1 = New-Object psobject 6 | New-UdfConnection ([ref]$SqlServer1) 7 | 8 | $global:SqlServer1.ConnectionType = 'ADO' 9 | $global:SqlServer1.DatabaseType = 'SqlServer' 10 | $global:SqlServer1.Server = '(local)' 11 | $global:SqlServer1.DatabaseName = 'Development' 12 | $global:SqlServer1.UseCredential = 'N' 13 | $global:SqlServer1.SetAuthenticationType('Integrated') 14 | $global:SqlServer1.BuildConnectionString() 15 | 16 | <# Send Order Load Email... #> 17 | function Send-UdfOrderLoadEmail ([string]$subject, [string]$body) 18 | { 19 | $credin = Get-Content ($global:rootfilepath + 'bryan') | convertto-securestring 20 | $credential = New-Object System.Management.Automation.PSCredential ` 21 | (“bryan@msn.com”, $credin) 22 | Send-MailMessage -smtpServer smtp.live.com -Credential $credential ` 23 | -from 'bryan@msn.com' -to 'bryan@msn.com' -subject "$subject" ` 24 | -Body "$body" -Usessl -Port 587 25 | } 26 | 27 | 28 | <# Order Load Workflow... #> 29 | Workflow Invoke-UdwOrderLoad 30 | { 31 | param([string] $sourceidentifier, [string] $sqlserver, [string] $databasename ) 32 | 33 | sequence 34 | { 35 | Write-Verbose $sourceidentifier 36 | Invoke-UdfOrderLoad 37 | 38 | $missing_emps = Get-UdfMissingEmployee | Where-Object -Property Employee_ID -ne $null 39 | 40 | if ($missing_emps.Count -gt 0) 41 | { 42 | Write-Verbose "Workflow Being Suspended." 43 | 44 | <# Mail commented out - uncomment after the function has been updated. 45 | Send-UdfOrderLoadEmail -subject "ETL Job Order Load - Suspended" ` 46 | -body "The ETL Job: Order Load has been suspended because the employee 47 | file has not been loaded. Please send the employee file as soon 48 | as possible." 49 | #> 50 | 51 | Checkpoint-Workflow 52 | Suspend-Workflow 53 | Write-Verbose "Workflow Resumed." 54 | Invoke-UdfEmployeeLoad 55 | <# Mail commented out - uncomment after the function has been updated. 56 | Send-UdfOrderLoadEmail -subject "ETL Job Order Load" ` 57 | -body "The ETL Job: Order Load has ended." 58 | #> 59 | } 60 | Else 61 | { 62 | Write-Verbose "finish" 63 | 64 | Invoke-UdfSQLQuery -sqlserver '(local)' -sqldatabase 'development' ` 65 | -sqlquery "update [dbo].[WorkFlowLog] set Status = 'complete' ` 66 | where WorkflowName = 'OrderLoad' and Status = 'suspended';" 67 | 68 | # Send-UdfOrderLoadEmail -subject "ETL Job Order Load" ` 69 | # -body "The ETL Job: Order Load has ended." 70 | } 71 | } 72 | } 73 | 74 | <# Log the Workflow Transformation.. #> 75 | function Invoke-UdfWorkflowLogTransformation 76 | { 77 | [CmdletBinding()] 78 | param ( 79 | [Parameter(ValueFromPipeline=$True)]$pipein = "default" 80 | ) 81 | process 82 | { 83 | 84 | $pipein | Add-Member -MemberType NoteProperty -Name "WorkflowName" ` 85 | -Value "OrderLoad" 86 | Return $pipein 87 | } 88 | } 89 | 90 | 91 | <# Run the Workflow... #> 92 | function Invoke-UdfWorkflow () 93 | { 94 | <# Define the mapping... #> 95 | $mappingset = @() # Create a collection object. 96 | $mappingset += (Add-UdfMapping "WorkflowName" "WorkflowName" "'" $false) 97 | $mappingset += (Add-UdfMapping "ID" "JobID" "" $false) 98 | $mappingset += (Add-UdfMapping "Name" "JobName" "'" $false) 99 | $mappingset += (Add-UdfMapping "Location" "Location" "'" $false) 100 | $mappingset += (Add-UdfMapping "Command" "Command" "'" $false) 101 | 102 | Try 103 | { 104 | Invoke-UdwOrderLoad -sourceidentifier 'Order' -sqlserver $global:SqlServer1.Server ` 105 | -databasename $global:SqlServer1.Databasename ` 106 | -AsJob -JobName OrderLoad | Invoke-UdfWorkflowLogTransformation | 107 | Select-Object -Property WorkflowName, ID, Name, Location, Command | 108 | Invoke-UdfSQLDML -Mapping $mappingset -DmlOperation "Insert" ` 109 | -Destinationtablename "dbo.WorkFlowLog" ` 110 | -Connection $global:SqlServer1 -Verbose 111 | } 112 | Catch 113 | { 114 | "Error: $error" 115 | } 116 | } 117 | 118 | <# Resume Workflow #> 119 | function Resume-UdfWorkflow () 120 | { 121 | Try 122 | { 123 | $job = Invoke-UdfSQLQuery -sqlserver $global:SqlServer1.Server ` 124 | -sqldatabase 'development' ` 125 | -sqlquery "select JobID from [dbo].[WorkFlowLog] where WorkflowName = 'OrderLoad' 126 | and Status = 'suspended';" ` 127 | 128 | Resume-Job -id $job.JobID -Wait 129 | 130 | Invoke-UdfSQLQuery -sqlserver $global:SqlServer1.Server ` 131 | –sqldatabase $global:SqlServer1.DatabaseName ` 132 | -sqlquery "update [dbo].[WorkFlowLog] set Status = 'complete' where WorkflowName = 133 | 'OrderLoad' and Status = 'suspended';" ` 134 | 135 | } 136 | Catch 137 | { 138 | "Error: $error" 139 | } 140 | } 141 | 142 | <# Register Order File Create Event #> 143 | function Register-UdfOrderFileCreateEvent([string] $source, [string] $filter, [string]$sourceidentifier) 144 | { 145 | try 146 | { 147 | $filesystemwatcher = New-Object IO.FileSystemWatcher $source, $filter -Property ` 148 | @{IncludeSubdirectories = $false; NotifyFilter = [IO.NotifyFilters]'FileName, LastWrite'} 149 | Register-ObjectEvent $filesystemwatcher Created -SourceIdentifier $sourceidentifier ` 150 | -Action { Invoke-UdfWorkflow } 151 | } 152 | catch 153 | { 154 | "Error registering file create event." 155 | } 156 | } 157 | 158 | <# Register Employee File Create Event #> 159 | function Register-UdfEmployeeFileCreateEvent([string] $source, [string] $filter, [string] $sourceidentifier) 160 | { 161 | try 162 | { 163 | $filesystemwatcher = New-Object IO.FileSystemWatcher $source, $filter -Property ` 164 | @{IncludeSubdirectories = $false; NotifyFilter = [IO.NotifyFilters]'FileName, LastWrite'} 165 | 166 | Register-ObjectEvent $filesystemwatcher Created -SourceIdentifier $sourceidentifier ` 167 | -Action { Resume-UdfWorkflow } 168 | } 169 | catch 170 | { 171 | "Error registring file create event." 172 | } 173 | } 174 | 175 | <# 176 | Poor Man's Hadoop functions start here... 177 | #> 178 | 179 | $filepath = $env:HOMEDRIVE + $env:HOMEPATH + "\Documents\" 180 | 181 | function New-UdfFile ([string]$fullfilepath) 182 | { 183 | for ($i=1; $i -le 1000; $i++) 184 | { 185 | Get-ChildItem | Out-File ($fullfilepath) -Append 186 | } 187 | } 188 | 189 | <# Use lines below to create test files... 190 | New-UdfFile ($filepath + "logfile1.txt") 191 | New-UdfFile ($filepath + "logfile2.txt") 192 | #> 193 | 194 | <# Search file... #> 195 | workflow Search-UdwFile ([string]$filepath, $filelist, $searchstring) 196 | { 197 | foreach -parallel ($file in $filelist) 198 | { 199 | Write-Verbose 'Processing searches...' 200 | 201 | inlinescript 202 | { 203 | function Search-UdfSingleFile ([string]$searchstring,[string] $outfilepath) 204 | { 205 | begin 206 | { 207 | "" > $outfilepath # Clear out file contents 208 | } 209 | process 210 | { 211 | if ($_ -like "*$searchstring*") 212 | { 213 | $_ >> $outfilepath 214 | } 215 | } 216 | } 217 | 218 | $sourcefile = $using:filepath + $using:file ; 219 | $outfile = $using:filepath + "out_" + $using:file ; 220 | "Writing output to $outfile." 221 | Get-Content $sourcefile | 222 | Search-UdfSingleFile -searchstring $using:searchstring -outfilepath $outfile 223 | } 224 | } 225 | } 226 | 227 | 228 | -------------------------------------------------------------------------------- /PPSFDD/Modules/umd_etl/umd_etl.psm1: -------------------------------------------------------------------------------- 1 | # Author: Bryan Cafferky Date: 2014-05-10 2 | # 3 | # Module: umd_etl.psm1 4 | # 5 | # Purpose: Provide common ETL functions to help load external files into SQL Server. 6 | # 7 | 8 | <# 9 | Author: Bryan Cafferky 2014-10-30 10 | 11 | Purpose: Send Email Message. 12 | 13 | Note: For Office365 use "smtp.office365.com" 14 | 15 | Get smptp settings from: 16 | http://email.about.com/od/Outlook.com/f/What-Are-The-Outlook-com-Smtp-Server-Settings.htm 17 | 18 | #> 19 | 20 | # Validate a value... 21 | function Invoke-UdfColumnValidation 22 | { 23 | [CmdletBinding()] 24 | param ( 25 | [string] $column, # value to be checked. 26 | [ValidateSet("minlength","maxlength","zipcode", "phonenumber", "emailaddress", "ssn", "minintvalue", "maxintvalue")] 27 | [string] $validation, # File name pattern to wait for. 28 | [parameter(Mandatory=$false)] 29 | [string] $validationvalue 30 | ) 31 | 32 | [boolean] $result = $false; 33 | 34 | Switch ($validation) 35 | { 36 | 37 | "minlength" { $result = ($column.Length -ge [int] $validationvalue); break } 38 | "maxlength" { $result = ($column.Length -le [int] $validationvalue); break } 39 | "zipcode" { $result = $column -match ("^\d{5}(-\d{4})?$") ; break } 40 | "phonenumber" { $result = $column -match ("\d{3}-\d{3}-\d{4}") ; break } 41 | "emailaddress" { $result = $column -match ("^[_a-z0-9-]+(\.[_a-z0-9-]+)*@[a-z0-9-]+(\.[a-z0-9-]+)*(\.[a-z]{2,4})$"); break } 42 | "ssn" { $result = $column -match ("^\d{3}-?\d{2}-?\d{4}$") ; break } 43 | "minintvalue" { $result = ([int]$column -ge [int] $validationvalue); break } 44 | "maxintvalue" { $result = ([int]$column -le [int] $validationvalue); break } 45 | 46 | } 47 | 48 | Write-Verbose "$column $validation $validationvalue" 49 | 50 | Return $result 51 | 52 | } 53 | 54 | 55 | function Add-UdfMapping 56 | { 57 | [CmdletBinding()] 58 | param ( 59 | [string] $incolumn , # Column from input pipeline. 60 | [string] $outcolumn , # Output column name. 61 | [string] $outcolumndelimiter , # Character to delimit output column. 62 | [boolean] $iskey # True = Key column, False = Not key column 63 | ) 64 | 65 | write-verbose $PSCmdlet.ParameterSetName 66 | 67 | $mapping = New-Object System.Object 68 | $mapping | Add-Member -MemberType NoteProperty -Name "InColumn" -Value "$incolumn" 69 | $mapping | Add-Member -MemberType NoteProperty -Name "OutColumn" -Value $outcolumn 70 | $mapping | Add-Member -MemberType NoteProperty -Name "OutColumnDelimiter" -Value "$outcolumndelimiter" 71 | $mapping | Add-Member -MemberType NoteProperty -Name "IsKey" -Value "$iskey" 72 | 73 | RETURN $mapping 74 | 75 | } 76 | 77 | function Get-UdfInColumnList 78 | { 79 | [CmdletBinding()] 80 | param ( 81 | [psobject] $mapping 82 | ) 83 | 84 | $inlist = "" # Just intializing 85 | foreach ($key in $mapping) 86 | { 87 | $inlist += $key.InColumn + ", " 88 | } 89 | 90 | $inlist = $inlist.Substring(0,$inlist.Length - 2) 91 | Return $inlist 92 | 93 | } 94 | # Get-UdfInColumnList $mappingset 95 | 96 | function Get-UdfOutColumnList { 97 | [CmdletBinding()] 98 | param ( 99 | [psobject] $mapping 100 | ) 101 | $outlist = "" # Just intializing 102 | foreach ($value in $mapping) 103 | { 104 | $outlist += $value.OutColumn + ", " 105 | } 106 | 107 | $outlist = $outlist.Substring(0,$outlist.Length - 2) 108 | Return $outlist 109 | 110 | } 111 | # Get-UdfOutColumnList $mappingset 112 | 113 | function Get-UdfSQLDML { 114 | [CmdletBinding()] 115 | param ( 116 | [psobject] $mapping, 117 | [parameter(mandatory=$true, 118 | HelpMessage="Enter the DML operation.")] 119 | [ValidateSet("Insert","Update","Merge", "Delete")] 120 | [string] $dmloperation, 121 | [string] $destinationtablename 122 | ) 123 | [string] $sqldml = "" 124 | Switch ($dmloperation) 125 | { 126 | Insert 127 | { 128 | $sqldml = "insert into $destinationtablename (" + (Get-UdfOutColumnList $mapping) + ") values (`$valuelist);" ; 129 | Write-Verbose $sqldml; break 130 | } 131 | 132 | Merge 133 | { 134 | $key = $mapping | Where-Object { $_.IsKey -eq $true } 135 | $sourcekey = $key.Incolumn 136 | $targetkey = $key.OutColumn 137 | $sourcecollist = (Get-UdfInColumnList $mapping); 138 | $insertstatement = "insert (" + (Get-UdfOutColumnList $mapping) + ") values (`$valuelist)"; 139 | 140 | $sqldml = " 141 | Merge into $destinationtablename as Target USING (VALUES ( `$valuelist )) as Source ( $sourcecollist ` 142 | ) ON Target.$targetkey = Source.$sourcekey ` 143 | WHEN MATCHED THEN ` 144 | UPDATE SET `$updatestatement 145 | WHEN NOT MATCHED BY TARGET THEN $insertstatement;"; break; 146 | } 147 | Delete 148 | { 149 | $key = $mapping | Where-Object { $_.IsKey -eq $true } 150 | $targetkey = $key.OutColumn 151 | $sqldml = "Delete from $destinationtablename where $targetkey = `$sourcekeyvalue;"; break 152 | } 153 | } 154 | 155 | Return $sqldml 156 | } 157 | 158 | function Invoke-UdfSQLDML 159 | { 160 | [CmdletBinding()] 161 | param ( 162 | [Parameter(ValueFromPipeline=$True)]$mypipe = "default", 163 | [Parameter(ValueFromPipeline=$False,Mandatory=$True,Position=1)] 164 | [psobject] $mapping, 165 | [parameter(ValueFromPipeline=$False,mandatory=$true,Position=2, 166 | HelpMessage="Enter the DML operation.")] 167 | [ValidateSet("Insert","Update","Merge", "Delete")] 168 | [string] $dmloperation, 169 | [Parameter(ValueFromPipeline=$False,Mandatory=$True,Position=3)] 170 | [string] $destinationtablename, 171 | [string] $server, 172 | [string] $database 173 | 174 | ) 175 | 176 | begin 177 | { 178 | $sqldml = Get-UdfSQLDML $mapping -dmloperation $dmloperation "$destinationtablename" 179 | $dbconn = Get-UdfOpenConnection $server $database 180 | $command = New-Object system.data.sqlclient.Sqlcommand($dbconn) 181 | } 182 | 183 | process 184 | { 185 | $values = "" 186 | $updatestatement = "" 187 | 188 | foreach($map in $mapping) 189 | { 190 | $prop = $map.InColumn.Replace("[", "") 191 | $prop = $prop.Replace("]", "") 192 | $delimiter = $map.OutColumnDelimiter 193 | $values = $values + $delimiter + $_.$prop + $delimiter + "," 194 | $updatestatement += $map.OutColumn + " = Source." + $map.InColumn + "," 195 | # Get the key column value... 196 | if ($map.IsKey -eq $true) 197 | { 198 | $sourcekeyvalue = $_.$prop 199 | } 200 | } 201 | 202 | $updatestatement = $updatestatement.Substring(0,$updatestatement.Length - 1) # Strip off the last comma. 203 | $valuelist = $values.Substring(0,$values.Length - 1) # Strip off the last comma. 204 | $sqlstatement = $ExecutionContext.InvokeCommand.ExpandString($sqldml) 205 | $sqlstatement = $sqlstatement.Replace(",,", ",null,") 206 | Write-Verbose $sqlstatement 207 | 208 | # Write to database... 209 | $command.Connection = $dbconn 210 | $command.CommandText = $sqlstatement 211 | $command.ExecuteNonQuery() 212 | } 213 | 214 | end 215 | { 216 | $dbconn.Close() 217 | } 218 | 219 | } 220 | 221 | 222 | function Get-UdfOpenConnection 223 | { 224 | [CmdletBinding()] 225 | param ( 226 | [string]$server, 227 | [string]$database 228 | ) 229 | 230 | Write-Verbose "open connecton" 231 | $conn = New-Object System.Data.SqlClient.SqlConnection("Data Source=$server;Integrated Security=SSPI;Initial Catalog=$database"); 232 | 233 | $conn.Open() 234 | 235 | Return $conn 236 | } 237 | 238 | 239 | 240 | -------------------------------------------------------------------------------- /PPSFDD/Modules/umd_join_object/umd_join_object.psm1: -------------------------------------------------------------------------------- 1 | function AddItemProperties($item, $properties, $output) 2 | { 3 | if($item -ne $null) 4 | { 5 | foreach($property in $properties) 6 | { 7 | $propertyHash =$property -as [hashtable] 8 | if($propertyHash -ne $null) 9 | { 10 | $hashName=$propertyHash["name"] -as [string] 11 | if($hashName -eq $null) 12 | { 13 | throw "there should be a string Name" 14 | } 15 | 16 | $expression=$propertyHash["expression"] -as [scriptblock] 17 | if($expression -eq $null) 18 | { 19 | throw "there should be a ScriptBlock Expression" 20 | } 21 | 22 | $_=$item 23 | $expressionValue=& $expression 24 | 25 | $output | add-member -MemberType "NoteProperty" -Name $hashName -Value $expressionValue 26 | } 27 | else 28 | { 29 | # .psobject.Properties allows you to list the properties of any object, also known as "reflection" 30 | foreach($itemProperty in $item.psobject.Properties) 31 | { 32 | if ($itemProperty.Name -like $property) 33 | { 34 | $output | add-member -MemberType "NoteProperty" -Name $itemProperty.Name -Value $itemProperty.Value 35 | } 36 | } 37 | } 38 | } 39 | } 40 | } 41 | 42 | 43 | function WriteJoinObjectOutput($leftItem, $rightItem, $leftProperties, $rightProperties, $Type) 44 | { 45 | $output = new-object psobject 46 | 47 | if($Type -eq "AllInRight") 48 | { 49 | # This mix of rightItem with LeftProperties and vice versa is due to 50 | # the switch of Left and Right arguments for AllInRight 51 | AddItemProperties $rightItem $leftProperties $output 52 | AddItemProperties $leftItem $rightProperties $output 53 | } 54 | else 55 | { 56 | AddItemProperties $leftItem $leftProperties $output 57 | AddItemProperties $rightItem $rightProperties $output 58 | } 59 | $output 60 | } 61 | 62 | <# 63 | .Synopsis 64 | Joins two lists of objects 65 | .DESCRIPTION 66 | Joins two lists of objects 67 | .EXAMPLE 68 | Join-Object $a $b "Id" ("Name","Salary") 69 | #> 70 | function Join-Object 71 | { 72 | [CmdletBinding()] 73 | [OutputType([int])] 74 | Param 75 | ( 76 | # List to join with $Right 77 | [Parameter(Mandatory=$true, 78 | Position=0)] 79 | [object[]] 80 | $Left, 81 | 82 | # List to join with $Left 83 | [Parameter(Mandatory=$true, 84 | Position=1)] 85 | [object[]] 86 | $Right, 87 | 88 | # Condition in which an item in the left matches an item in the right 89 | # typically something like: {$args[0].Id -eq $args[1].Id} 90 | [Parameter(Mandatory=$true, 91 | Position=2)] 92 | [scriptblock] 93 | $Where, 94 | 95 | # Properties from $Left we want in the output. 96 | # Each property can: 97 | # - Be a plain property name like "Name" 98 | # - Contain wildcards like "*" 99 | # - Be a hashtable like @{Name="Product Name";Expression={$_.Name}}. Name is the output property name 100 | # and Expression is the property value. The same syntax is available in select-object and it is 101 | # important for join-object because joined lists could have a property with the same name 102 | [Parameter(Mandatory=$true, 103 | Position=3)] 104 | [object[]] 105 | $LeftProperties, 106 | 107 | # Properties from $Right we want in the output. 108 | # Like LeftProperties, each can be a plain name, wildcard or hashtable. See the LeftProperties comments. 109 | [Parameter(Mandatory=$true, 110 | Position=4)] 111 | [object[]] 112 | $RightProperties, 113 | 114 | # Type of join. 115 | # AllInLeft will have all elements from Left at least once in the output, and might appear more than once 116 | # if the where clause is true for more than one element in right, Left elements with matches in Right are 117 | # preceded by elements with no matches. This is equivalent to an outer left join (or simply left join) 118 | # SQL statement. 119 | # AllInRight is similar to AllInLeft. 120 | # OnlyIfInBoth will cause all elements from Left to be placed in the output, only if there is at least one 121 | # match in Right. This is equivalent to a SQL inner join (or simply join) statement. 122 | # AllInBoth will have all entries in right and left in the output. Specifically, it will have all entries 123 | # in right with at least one match in left, followed by all entries in Right with no matches in left, 124 | # followed by all entries in Left with no matches in Right.This is equivallent to a SQL full join. 125 | [Parameter(Mandatory=$false, 126 | Position=5)] 127 | [ValidateSet("AllInLeft","OnlyIfInBoth","AllInBoth", "AllInRight")] 128 | [string] 129 | $Type="OnlyIfInBoth" 130 | ) 131 | 132 | Begin 133 | { 134 | # a list of the matches in right for each object in left 135 | $leftMatchesInRight = new-object System.Collections.ArrayList 136 | 137 | # the count for all matches 138 | $rightMatchesCount = New-Object "object[]" $Right.Count 139 | 140 | for($i=0;$i -lt $Right.Count;$i++) 141 | { 142 | $rightMatchesCount[$i]=0 143 | } 144 | } 145 | 146 | Process 147 | { 148 | if($Type -eq "AllInRight") 149 | { 150 | # for AllInRight we just switch Left and Right 151 | $aux = $Left 152 | $Left = $Right 153 | $Right = $aux 154 | } 155 | 156 | # go over items in $Left and produce the list of matches 157 | foreach($leftItem in $Left) 158 | { 159 | $leftItemMatchesInRight = new-object System.Collections.ArrayList 160 | $null = $leftMatchesInRight.Add($leftItemMatchesInRight) 161 | 162 | for($i=0; $i -lt $right.Count;$i++) 163 | { 164 | $rightItem=$right[$i] 165 | 166 | if($Type -eq "AllInRight") 167 | { 168 | # For AllInRight, we want $args[0] to refer to the left and $args[1] to refer to right, 169 | # but since we switched left and right, we have to switch the where arguments 170 | $whereLeft = $rightItem 171 | $whereRight = $leftItem 172 | } 173 | else 174 | { 175 | $whereLeft = $leftItem 176 | $whereRight = $rightItem 177 | } 178 | 179 | if(Invoke-Command -ScriptBlock $where -ArgumentList $whereLeft,$whereRight) 180 | { 181 | $null = $leftItemMatchesInRight.Add($rightItem) 182 | $rightMatchesCount[$i]++ 183 | } 184 | 185 | } 186 | } 187 | 188 | # go over the list of matches and produce output 189 | for($i=0; $i -lt $left.Count;$i++) 190 | { 191 | $leftItemMatchesInRight=$leftMatchesInRight[$i] 192 | $leftItem=$left[$i] 193 | 194 | if($leftItemMatchesInRight.Count -eq 0) 195 | { 196 | if($Type -ne "OnlyIfInBoth") 197 | { 198 | WriteJoinObjectOutput $leftItem $null $LeftProperties $RightProperties $Type 199 | } 200 | 201 | continue 202 | } 203 | 204 | foreach($leftItemMatchInRight in $leftItemMatchesInRight) 205 | { 206 | WriteJoinObjectOutput $leftItem $leftItemMatchInRight $LeftProperties $RightProperties $Type 207 | } 208 | } 209 | } 210 | 211 | End 212 | { 213 | #produce final output for members of right with no matches for the AllInBoth option 214 | if($Type -eq "AllInBoth") 215 | { 216 | for($i=0; $i -lt $right.Count;$i++) 217 | { 218 | $rightMatchCount=$rightMatchesCount[$i] 219 | if($rightMatchCount -eq 0) 220 | { 221 | $rightItem=$Right[$i] 222 | WriteJoinObjectOutput $null $rightItem $LeftProperties $RightProperties $Type 223 | } 224 | } 225 | } 226 | } 227 | } 228 | 229 | -------------------------------------------------------------------------------- /PPSFDD/Data/currencyexchangerate.csv: -------------------------------------------------------------------------------- 1 | CurrencyCD,CurrencyName,UnitsPerUSD,USDPerUnit,AsOfDate 2 | USD,US Dollar,1,1,2014-12-22 3 | EUR,Euro,0.818212032,1.22217709,2014-12-22 4 | GBP,British Pound,0.642000195,1.557631925,2014-12-22 5 | INR,Indian Rupee,63.22431935,0.015816699,2014-12-22 6 | AUD,Australian Dollar,1.231610305,0.811945139,2014-12-22 7 | CAD,Canadian Dollar,1.16453374,0.858712776,2014-12-22 8 | SGD,Singapore Dollar,1.319113699,0.758084766,2014-12-22 9 | CHF,Swiss Franc,0.984515792,1.015727739,2014-12-22 10 | MYR,Malaysian Ringgit,3.493839223,0.286218093,2014-12-22 11 | JPY,Japanese Yen,120.1733949,0.008321309,2014-12-22 12 | CNY,Chinese Yuan Renminbi,6.222956485,0.160695323,2014-12-22 13 | NZD,New Zealand Dollar,1.295049835,0.772171057,2014-12-22 14 | THB,Thai Baht,32.89760807,0.030397347,2014-12-22 15 | HUF,Hungarian Forint,256.7086866,0.003895466,2014-12-22 16 | AED,Emirati Dirham,3.673138703,0.27224673,2014-12-22 17 | HKD,Hong Kong Dollar,7.755423952,0.128942016,2014-12-22 18 | MXN,Mexican Peso,14.67430881,0.06814631,2014-12-22 19 | ZAR,South African Rand,11.57534742,0.086390496,2014-12-22 20 | PHP,Philippine Peso,44.62024268,0.022411353,2014-12-22 21 | SEK,Swedish Krona,7.806368525,0.128100537,2014-12-22 22 | IDR,Indonesian Rupiah,12451.71182,8.03102E-05,2014-12-22 23 | SAR,Saudi Arabian Riyal,3.75389845,0.266389731,2014-12-22 24 | BRL,Brazilian Real,2.664590637,0.375292169,2014-12-22 25 | TRY,Turkish Lira,2.31482388,0.431998308,2014-12-22 26 | KES,Kenyan Shilling,90.39160815,0.011062974,2014-12-22 27 | KRW,South Korean Won,1100.09376,0.000909013,2014-12-22 28 | EGP,Egyptian Pound,7.151160971,0.139837434,2014-12-22 29 | IQD,Iraqi Dinar,1148.014555,0.000871069,2014-12-22 30 | NOK,Norwegian Krone,7.43340217,0.134527902,2014-12-22 31 | KWD,Kuwaiti Dinar,0.292808963,3.415195999,2014-12-22 32 | RUB,Russian Ruble,54.92149409,0.018207808,2014-12-22 33 | DKK,Danish Krone,6.089129811,0.164227079,2014-12-22 34 | PKR,Pakistani Rupee,100.564938,0.009943824,2014-12-22 35 | ILS,Israeli Shekel,3.90765893,0.255907698,2014-12-22 36 | PLN,Polish Zloty,3.487148111,0.286767286,2014-12-22 37 | QAR,Qatari Riyal,3.641533094,0.274609615,2014-12-22 38 | XAU,Gold Ounce,0.00085115,1174.880624,2014-12-22 39 | OMR,Omani Rial,0.385001944,2.597389485,2014-12-22 40 | COP,Colombian Peso,2328.921695,0.000429383,2014-12-22 41 | CLP,Chilean Peso,608.8328869,0.001642487,2014-12-22 42 | TWD,Taiwan New Dollar,31.58153503,0.031664072,2014-12-22 43 | ARS,Argentine Peso,8.550607302,0.116950757,2014-12-22 44 | CZK,Czech Koruna,22.57340902,0.044299911,2014-12-22 45 | VND,Vietnamese Dong,21287.56219,4.69758E-05,2014-12-22 46 | MAD,Moroccan Dirham,8.991895938,0.111211251,2014-12-22 47 | JOD,Jordanian Dinar,0.710199778,1.408054511,2014-12-22 48 | BHD,Bahraini Dinar,0.377045545,2.652199482,2014-12-22 49 | XOF,CFA Franc,536.7119098,0.001863197,2014-12-22 50 | LKR,Sri Lankan Rupee,131.2681155,0.007617996,2014-12-22 51 | UAH,Ukrainian Hryvnia,15.90133713,0.062887793,2014-12-22 52 | NGN,Nigerian Naira,184.5525627,0.005418511,2014-12-22 53 | TND,Tunisian Dinar,1.870413552,0.534641122,2014-12-22 54 | UGX,Ugandan Shilling,2754.941621,0.000362984,2014-12-22 55 | RON,Romanian New Leu,3.654437905,0.273639894,2014-12-22 56 | BDT,Bangladeshi Taka,77.87003828,0.01284191,2014-12-22 57 | PEN,Peruvian Nuevo Sol,2.970347339,0.336660965,2014-12-22 58 | GEL,Georgian Lari,1.892374959,0.5284365,2014-12-22 59 | XAF,Central African CFA Franc BEAC,536.7119098,0.001863197,2014-12-22 60 | FJD,Fijian Dollar,1.995597722,0.501102997,2014-12-22 61 | VEF,Venezuelan Bolivar,6.343137648,0.157650686,2014-12-22 62 | BYR,Belarusian Ruble,11036.83876,9.06057E-05,2014-12-22 63 | HRK,Croatian Kuna,6.269073406,0.159513206,2014-12-22 64 | UZS,Uzbekistani Som,2415.565229,0.000413982,2014-12-22 65 | BGN,Bulgarian Lev,1.599882742,0.625045807,2014-12-22 66 | DZD,Algerian Dinar,87.24041628,0.011462577,2014-12-22 67 | IRR,Iranian Rial,27029.30646,3.69969E-05,2014-12-22 68 | DOP,Dominican Peso,44.25745144,0.022595065,2014-12-22 69 | ISK,Icelandic Krona,126.6704682,0.0078945,2014-12-22 70 | XAG,Silver Ounce,0.0638752,15.65552821,2014-12-22 71 | CRC,Costa Rican Colon,532.471143,0.001878036,2014-12-22 72 | SYP,Syrian Pound,177.2899003,0.005640479,2014-12-22 73 | LYD,Libyan Dinar,1.315,0.760456274,2014-12-22 74 | JMD,Jamaican Dollar,114.2957103,0.008749235,2014-12-22 75 | MUR,Mauritian Rupee,31.50412561,0.031741875,2014-12-22 76 | GHS,Ghanaian Cedi,3.213652355,0.311172426,2014-12-22 77 | AOA,Angolan Kwanza,102.1921118,0.009785491,2014-12-22 78 | UYU,Uruguayan Peso,24.01598433,0.041638935,2014-12-22 79 | AFN,Afghan Afghani,58.01829497,0.017235943,2014-12-22 80 | LBP,Lebanese Pound,1512.845952,0.000661006,2014-12-22 81 | XPF,CFP Franc,97.63866729,0.010241844,2014-12-22 82 | TTD,Trinidadian Dollar,6.3434065,0.157644004,2014-12-22 83 | TZS,Tanzanian Shilling,1697.076527,0.000589249,2014-12-22 84 | ALL,Albanian Lek,114.4491574,0.008737504,2014-12-22 85 | XCD,East Caribbean Dollar,2.700002596,0.370370014,2014-12-22 86 | GTQ,Guatemalan Quetzal,7.615337251,0.131313948,2014-12-22 87 | NPR,Nepalese Rupee,101.2093974,0.009880505,2014-12-22 88 | BOB,Bolivian Boliviano,6.905669243,0.144808557,2014-12-22 89 | ZWD,Zimbabwean Dollar,361.9,0.002763194,2014-12-22 90 | BBD,Barbadian or Bajan Dollar,2,0.5,2014-12-22 91 | CUC,Cuban Convertible Peso,1,1,2014-12-22 92 | LAK,Lao or Laotian Kip,8087.886034,0.000123642,2014-12-22 93 | BND,Bruneian Dollar,1.319113699,0.758084766,2014-12-22 94 | BWP,Botswana Pula,9.501097761,0.105250996,2014-12-22 95 | HNL,Honduran Lempira,21.02039559,0.047572844,2014-12-22 96 | PYG,Paraguayan Guarani,4629.233303,0.000216019,2014-12-22 97 | ETB,Ethiopian Birr,20.1779708,0.049558997,2014-12-22 98 | NAD,Namibian Dollar,11.57534742,0.086390496,2014-12-22 99 | PGK,Papua New Guinean Kina,2.577286368,0.388005001,2014-12-22 100 | SDG,Sudanese Pound,5.682449493,0.175980447,2014-12-22 101 | MOP,Macau Pataca,7.988086671,0.125186423,2014-12-22 102 | NIO,Nicaraguan Cordoba,26.56608266,0.037641982,2014-12-22 103 | BMD,Bermudian Dollar,1,1,2014-12-22 104 | KZT,Kazakhstani Tenge,182.1003772,0.005491477,2014-12-22 105 | PAB,Panamanian Balboa,1,1,2014-12-22 106 | BAM,Bosnian Convertible Marka,1.600283638,0.624889223,2014-12-22 107 | GYD,Guyanese Dollar,206.8522886,0.004834368,2014-12-22 108 | YER,Yemeni Rial,215.0343117,0.004650421,2014-12-22 109 | MGA,Malagasy Ariary,2585.817004,0.000386725,2014-12-22 110 | KYD,Caymanian Dollar,0.820000126,1.219512008,2014-12-22 111 | MZN,Mozambican Metical,33.95421689,0.029451423,2014-12-22 112 | RSD,Serbian Dinar,99.30466896,0.01007002,2014-12-22 113 | SCR,Seychellois Rupee,13.87812431,0.072055847,2014-12-22 114 | AMD,Armenian Dram,455.687159,0.002194488,2014-12-22 115 | SBD,Solomon Islander Dollar,7.645259939,0.1308,2014-12-22 116 | AZN,Azerbaijani New Manat,0.785697789,1.272753996,2014-12-22 117 | SLL,Sierra Leonean Leone,4252.364249,0.000235163,2014-12-22 118 | TOP,Tongan Pa'anga,2.031199418,0.492319952,2014-12-22 119 | BZD,Belizean Dollar,1.993718319,0.501575368,2014-12-22 120 | MWK,Malawian Kwacha,480.0761565,0.002083003,2014-12-22 121 | GMD,Gambian Dalasi,43.06472905,0.023220859,2014-12-22 122 | BIF,Burundian Franc,1551.815433,0.000644407,2014-12-22 123 | SOS,Somali Shilling,824.9667951,0.00121217,2014-12-22 124 | HTG,Haitian Gourde,46.65822741,0.021432447,2014-12-22 125 | GNF,Guinean Franc,7020.844478,0.000142433,2014-12-22 126 | MVR,Maldivian Rufiyaa,15.36889801,0.065066474,2014-12-22 127 | MNT,Mongolian Tughrik,1868.308793,0.000535243,2014-12-22 128 | CDF,Congolese Franc,916.6086761,0.001090978,2014-12-22 129 | STD,Sao Tomean Dobra,19958.88671,0.000050103,2014-12-22 130 | TJS,Tajikistani Somoni,5.130099156,0.194928006,2014-12-22 131 | KPW,North Korean Won,132.3435843,0.00755609,2014-12-22 132 | MMK,Burmese Kyat,1030.592406,0.000970316,2014-12-22 133 | LSL,Basotho Loti,11.57534742,0.086390496,2014-12-22 134 | LRD,Liberian Dollar,92.49992138,0.01081082,2014-12-22 135 | KGS,Kyrgyzstani Som,57.60035463,0.017361004,2014-12-22 136 | GIP,Gibraltar Pound,0.642000195,1.557631925,2014-12-22 137 | XPT,Platinum Ounce,0.000846007,1182.022976,2014-12-22 138 | MDL,Moldovan Leu,15.6614067,0.063851225,2014-12-22 139 | CUP,Cuban Peso,26.5,0.037735849,2014-12-22 140 | KHR,Cambodian Riel,4049.368856,0.000246952,2014-12-22 141 | MKD,Macedonian Denar,50.20366706,0.019918864,2014-12-22 142 | VUV,Ni-Vanuatu Vatu,104.166384,0.009600026,2014-12-22 143 | MRO,Mauritanian Ouguiya,292.5888965,0.003417765,2014-12-22 144 | ANG,Dutch Guilder,1.788030557,0.559274558,2014-12-22 145 | SZL,Swazi Lilangeni,11.57534742,0.086390496,2014-12-22 146 | CVE,Cape Verdean Escudo,89.28379693,0.011200241,2014-12-22 147 | SRD,Surinamese Dollar,3.294822651,0.303506472,2014-12-22 148 | XPD,Palladium Ounce,0.001232402,811.4234144,2014-12-22 149 | SVC,Salvadoran Colon,8.75,0.114285714,2014-12-22 150 | BSD,Bahamian Dollar,1,1,2014-12-22 151 | XDR,IMF Special Drawing Rights,0.689149997,1.45106291,2014-12-22 152 | RWF,Rwandan Franc,687.7546827,0.001454007,2014-12-22 153 | AWG,Aruban or Dutch Guilder,1.79,0.558659218,2014-12-22 154 | DJF,Djiboutian Franc,177.9901028,0.00561829,2014-12-22 155 | BTN,Bhutanese Ngultrum,63.22431935,0.015816699,2014-12-22 156 | KMF,Comoran Franc,402.5339324,0.002484263,2014-12-22 157 | WST,Samoan Tala,2.439819935,0.409866313,2014-12-22 158 | SPL,Seborgan Luigino,0.166666667,6,2014-12-22 159 | ERN,Eritrean Nakfa,10.46999712,0.09551101,2014-12-22 160 | FKP,Falkland Island Pound,0.642000195,1.557631925,2014-12-22 161 | SHP,Saint Helenian Pound,0.642000195,1.557631925,2014-12-22 162 | JEP,Jersey Pound,0.642000195,1.557631925,2014-12-22 163 | TMT,Turkmenistani Manat,2.85,0.350877193,2014-12-22 164 | TVD,Tuvaluan Dollar,1.231610305,0.811945139,2014-12-22 165 | IMP,Isle of Man Pound,0.642000195,1.557631925,2014-12-22 166 | GGP,Guernsey Pound,0.642000195,1.557631925,2014-12-22 167 | -------------------------------------------------------------------------------- /PPSFDD/Modules/umd_northwind_etl/umd_northwind_etl.psm1: -------------------------------------------------------------------------------- 1 | <# Data specific functions that are part of the Northwind ETL #> 2 | 3 | Import-Module umd_database 4 | Import-Module umd_etl_functions 5 | Import-Module umd_join_object 6 | 7 | function Invoke-UdfStateSalesTaxLoad 8 | { 9 | 10 | # State Code List #> 11 | $global:referencepath = $env:HomeDrive + $env:HOMEPATH + "\Documents\" 12 | 13 | $salestax = Import-CSV ($global:referencepath + "StateSalesTaxRates.csv") 14 | 15 | <# Define the mapping... #> 16 | $mappingset = @() # Create a collection object. 17 | $mappingset += (Add-UdfMapping "StateCode" "StateProvinceCD" "'" $true) 18 | $mappingset += (Add-UdfMapping "SalesTaxRate" "StateProvinceSalesTaxRate" "" $false) 19 | 20 | <# Define the SQL Server Target #> 21 | [psobject] $SqlServer1 = New-Object psobject 22 | New-UdfConnection ([ref]$SqlServer1) 23 | 24 | $SqlServer1.ConnectionType = 'ADO' 25 | $SqlServer1.DatabaseType = 'SqlServer' 26 | $SqlServer1.Server = '(local)' 27 | $SqlServer1.DatabaseName = 'Development' 28 | $SqlServer1.UseCredential = 'N' 29 | $SqlServer1.SetAuthenticationType('Integrated') 30 | $SqlServer1.BuildConnectionString() 31 | 32 | # Load the table… 33 | $SqlServer1.RunSQL("truncate table [dbo].[StateSalesTaxRate]", $false) 34 | $salestax | Invoke-UdfSQLDML -Mapping $mappingset -DmlOperation "Insert" -Destinationtablename "dbo.StateSalesTaxRate" -Connection $SqlServer1 -Verbose 35 | 36 | } 37 | 38 | function Invoke-UdfProductsTransformation 39 | { 40 | [CmdletBinding()] 41 | param ( 42 | [Parameter(ValueFromPipeline=$True)]$mypipe = "default" 43 | ) 44 | process 45 | { 46 | if ($mypipe."Minimum Reorder Quantity" -eq [DBNull]::Value) { $mypipe."Minimum Reorder Quantity" = 0 } 47 | 48 | Return $mypipe 49 | } 50 | } 51 | 52 | function Invoke-UdfProductLoad 53 | { 54 | 55 | <# Define the mapping... #> 56 | $mappingset = @() # Create a collection object. 57 | $mappingset += (Add-UdfMapping "[Supplier IDs]" "SupplierIDs" "'" $false) 58 | $mappingset += (Add-UdfMapping "[ID]" "ID" "" $true) 59 | $mappingset += (Add-UdfMapping "[Product Code]" "ProductCode" "'" $false) 60 | $mappingset += (Add-UdfMapping "[Product Name]" "ProductName" "'" $false) 61 | $mappingset += (Add-UdfMapping "[Description]" "Description" "'" $false) 62 | $mappingset += (Add-UdfMapping "[Standard Cost]" "StandardCost" "" $false) 63 | $mappingset += (Add-UdfMapping "[Reorder Level]" "ReorderLevel" "" $false) 64 | $mappingset += (Add-UdfMapping "[Target Level]" "TargetLevel" "" $false) 65 | $mappingset += (Add-UdfMapping "[List Price]" "ListPrice" "" $false) 66 | $mappingset += (Add-UdfMapping "[Quantity Per Unit]" "QuantityPerUnit" "'" $false) 67 | $mappingset += (Add-UdfMapping "[Discontinued]" "Discontinued" "'" $false) 68 | $mappingset += (Add-UdfMapping "[Minimum Reorder Quantity]" "MinimumReorderQuantity" "" $false) 69 | $mappingset += (Add-UdfMapping "[Category]" "Category" "'" $false) 70 | $mappingset += (Add-UdfMapping "[Attachments]" "Attachments" "'" $false) 71 | 72 | $global:referencepath = $env:HomeDrive + $env:HOMEPATH + "\Documents\" 73 | 74 | <# Create the Access database connection object #> 75 | [psobject] $access1 = New-Object psobject 76 | New-UdfConnection ([ref]$access1) 77 | $access1.ConnectionType = 'ODBC' 78 | $access1.DatabaseType = 'Access' 79 | $access1.DatabaseName = ($global:referencepath + 'DesktopNorthwind2007.accdb') 80 | $access1.UseCredential = 'N' 81 | $access1.SetAuthenticationType('DSNLess') 82 | $access1.Driver = "Microsoft Access Driver (*.mdb, *.accdb)" 83 | $access1.BuildConnectionString() 84 | 85 | <# Create the SQL Server connection object #> 86 | [psobject] $SqlServer1 = New-Object psobject 87 | New-UdfConnection ([ref]$SqlServer1) 88 | 89 | $SqlServer1.ConnectionType = 'ADO' 90 | $SqlServer1.DatabaseType = 'SqlServer' 91 | $SqlServer1.Server = '(local)' 92 | $SqlServer1.DatabaseName = 'Development' 93 | $SqlServer1.UseCredential = 'N' 94 | $SqlServer1.SetAuthenticationType('Integrated') 95 | $SqlServer1.BuildConnectionString() 96 | 97 | $access1.RunSQL("select * from Products order by id", $true) | Invoke-UdfProductsTransformation ` 98 | | Invoke-UdfSQLDML -Mapping $mappingset -DmlOperation "Merge" -Destinationtablename "[dbo].Products" -connection $SqlServer1 –Verbose 99 | 100 | } 101 | 102 | function Invoke-UdfOrdersTransformation 103 | { 104 | [CmdletBinding()] 105 | param ( 106 | [Parameter(ValueFromPipeline=$True)]$pipein = "default", 107 | [Parameter(ValueFromPipeline=$false)]$filepath 108 | ) 109 | process 110 | { 111 | 112 | $statetaxcsv = Import-CSV ("$filepath" + "StateSalesTaxRates.csv" ) 113 | [hashtable] $statetaxht = @{} 114 | foreach ($item in $statetaxcsv) {$statetaxht.Add($item.StateCode, $item.SalesTaxRate) } 115 | 116 | [psobject] $pipeout = New-Object psobject 117 | 118 | $pipeout | Add-Member -MemberType NoteProperty -Name "Employee_ID" ` 119 | -Value $pipein.Employee_x0020_ID 120 | $pipeout | Add-Member -MemberType NoteProperty -Name "Order_Date" ` 121 | -Value $pipein.Order_x0020_Date 122 | $pipeout | Add-Member -MemberType NoteProperty -Name "Ship_City" ` 123 | -Value $pipein.Ship_x0020_City 124 | $pipeout | Add-Member -MemberType NoteProperty -Name "Ship_State" ` 125 | -Value $pipein.Ship_x0020_State_x0020_Province 126 | $pipeout | Add-Member -MemberType NoteProperty -Name "Status_ID" ` 127 | -Value $pipein.Status_x0020_ID 128 | $pipeout | Add-Member -MemberType NoteProperty -Name "Order_ID" ` 129 | -Value $pipein.Order_x0020_ID 130 | $pipeout | Add-Member -MemberType NoteProperty -Name "Customer_ID" ` 131 | -Value $pipein.Customer_x0020_ID 132 | 133 | $pipeout | Add-Member -MemberType NoteProperty -Name "Sales_Tax_Rate" ` 134 | -Value 0 135 | 136 | $pipeout.Sales_Tax_Rate = $statetaxht[$pipein.Ship_x0020_State_x002F_Province] 137 | 138 | Return $pipeout 139 | } 140 | } 141 | 142 | function Invoke-UdfOrderLoad 143 | { 144 | <# Define the MS Access Connection - Caution: 32 bit ISE only #> 145 | $global:referencepath = $env:HomeDrive + $env:HOMEPATH + "\Documents\" 146 | 147 | <# Load orders #> 148 | [xml]$orders = Get-Content ("$global:referencepath" + "Orders.XML" ) 149 | 150 | <# Define the mapping... #> 151 | $mappingset = @() # Create a collection object. 152 | $mappingset += (Add-UdfMapping "Order_ID" "Order_ID" "" $true) 153 | $mappingset += (Add-UdfMapping "Employee_ID" "Employee_ID" "" $false) 154 | $mappingset += (Add-UdfMapping "Order_Date" "Order_Date" "'" $false) 155 | $mappingset += (Add-UdfMapping "Ship_City" "Ship_City" "'" $false) 156 | $mappingset += (Add-UdfMapping "Ship_State" "Ship_State" "'" $false) 157 | $mappingset += (Add-UdfMapping "Status_ID" "Status_ID" "" $false) 158 | $mappingset += (Add-UdfMapping "Customer_ID" "Customer_ID" "" $false) 159 | $mappingset += (Add-UdfMapping "Sales_Tax_Rate" "Sales_Tax_Rate" "" $false) 160 | 161 | 162 | <# Define the SQL Server Target #> 163 | [psobject] $SqlServer1 = New-Object psobject 164 | New-UdfConnection ([ref]$SqlServer1) 165 | 166 | $SqlServer1.ConnectionType = 'ADO' 167 | $SqlServer1.DatabaseType = 'SqlServer' 168 | $SqlServer1.Server = '(local)' 169 | $SqlServer1.DatabaseName = 'Development' 170 | $SqlServer1.UseCredential = 'N' 171 | $SqlServer1.SetAuthenticationType('Integrated') 172 | $SqlServer1.BuildConnectionString() 173 | 174 | $orders.dataroot.orders | Invoke-UdfOrdersTransformation -filepath $global:referencepath ` 175 | | Invoke-UdfSQLDML -Mapping $mappingset -DmlOperation "Merge" -Destinationtablename "dbo.Orders" -connection $SqlServer1 -Verbose 176 | 177 | } 178 | 179 | function Get-UdfMissingEmployee 180 | { 181 | 182 | <# Define the SQL Server Target #> 183 | [psobject] $SqlServer1 = New-Object psobject 184 | New-UdfConnection ([ref]$SqlServer1) 185 | 186 | $SqlServer1.ConnectionType = 'ADO' 187 | $SqlServer1.DatabaseType = 'SqlServer' 188 | $SqlServer1.Server = '(local)' 189 | $SqlServer1.DatabaseName = 'Development' 190 | $SqlServer1.UseCredential = 'N' 191 | $SqlServer1.SetAuthenticationType('Integrated') 192 | $SqlServer1.BuildConnectionString() 193 | 194 | <# Load the data. #> 195 | $missing_employees = $SqlServer1.RunSQL(" 196 | select Employee_ID, count(*) as OrderCount 197 | from dbo.Orders o 198 | left join [dbo].[Employees] e 199 | on (o.Employee_ID = e.ID) 200 | where e.ID is null 201 | Group By Employee_ID;", $True) 202 | 203 | Return $missing_employees 204 | } 205 | 206 | function Invoke-UdfCustomersTransformation 207 | { 208 | [CmdletBinding()] 209 | param ( 210 | [Parameter(ValueFromPipeline=$True)]$pipein = "default" 211 | ) 212 | process 213 | { 214 | 215 | [psobject] $pipeout = New-Object psobject 216 | 217 | $pipeout | Add-Member -MemberType NoteProperty -Name "Customer_ID" ` 218 | -Value $pipein.substring(0,10).trim() 219 | 220 | $pipeout | Add-Member -MemberType NoteProperty -Name "Company_Name" ` 221 | -Value $pipein.substring(11,50).trim() 222 | 223 | $pipeout | Add-Member -MemberType NoteProperty -Name "Last_Name" ` 224 | -Value $pipein.substring(61,50).trim() 225 | 226 | $pipeout | Add-Member -MemberType NoteProperty -Name "First_Name" ` 227 | -Value $pipein.substring(111,50).trim() 228 | 229 | $pipeout | Add-Member -MemberType NoteProperty -Name "Title" ` 230 | -Value $pipein.substring(211,50).trim() 231 | 232 | $pipeout | Add-Member -MemberType NoteProperty -Name "City" ` 233 | -Value $pipein.substring(873,50).trim() 234 | 235 | $pipeout | Add-Member -MemberType NoteProperty -Name "State" ` 236 | -Value $pipein.substring(923,50).trim() 237 | 238 | $pipeout | Add-Member -MemberType NoteProperty -Name "Zip" ` 239 | -Value $pipein.substring(973,15).trim() 240 | 241 | $pipeout | Add-Member -MemberType NoteProperty -Name "Country" ` 242 | -Value $pipein.substring(988,50).trim() 243 | Return $pipeout 244 | 245 | } 246 | } 247 | 248 | function Invoke-UdfCustomerLoad 249 | { 250 | <# Define the MS Access Connection - Caution: 32 bit ISE only #> 251 | $global:referencepath = $env:HomeDrive + $env:HOMEPATH + "\Documents\" 252 | 253 | # Load the tables into variables... 254 | $customer = Get-Content ("$global:referencepath" + "customers.txt" ) | Invoke-UdfCustomersTransformation | ` 255 | Sort-Object -Property State 256 | 257 | $states = Import-CSV ("$global:referencepath" + "state_table.csv" ) | Sort-Object -Property abbreviation 258 | 259 | <# Define the mapping and include the columns coming from the joined table... #> 260 | $mappingset = @() # Create a collection object. 261 | $mappingset += (Add-UdfMapping "Customer_ID" "Customer_ID" "" $true) 262 | $mappingset += (Add-UdfMapping "Company_Name" "Company_Name" "'" $false) 263 | $mappingset += (Add-UdfMapping "Last_Name" "Last_Name" "'" $false) 264 | $mappingset += (Add-UdfMapping "First_Name" "First_Name" "'" $false) 265 | $mappingset += (Add-UdfMapping "Title" "Title" "'" $false) 266 | $mappingset += (Add-UdfMapping "City" "City" "'" $false) 267 | $mappingset += (Add-UdfMapping "State" "State" "'" $false) 268 | $mappingset += (Add-UdfMapping "Zip" "Zip" "" $false) 269 | $mappingset += (Add-UdfMapping "Country" "Country" "'" $false) 270 | $mappingset += (Add-UdfMapping "name" "State_Name" "'" $false) 271 | $mappingset += (Add-UdfMapping "census_region_name" "State_Region" "'" $false) 272 | 273 | <# Define the SQL Server Target #> 274 | [psobject] $SqlServer1 = New-Object psobject 275 | New-UdfConnection ([ref]$SqlServer1) 276 | 277 | $SqlServer1.ConnectionType = 'ADO' 278 | $SqlServer1.DatabaseType = 'SqlServer' 279 | $SqlServer1.Server = '(local)' 280 | $SqlServer1.DatabaseName = 'Development' 281 | $SqlServer1.UseCredential = 'N' 282 | $SqlServer1.SetAuthenticationType('Integrated') 283 | $SqlServer1.BuildConnectionString() 284 | 285 | <# Load the data. #> 286 | $SqlServer1.RunSQL("truncate table [dbo].[Customers]", $false) 287 | 288 | Join-Object -Left $customer -Right $states ` 289 | -Where {$args[0].State -eq $args[1].abbreviation} –LeftProperties "*" ` 290 | –RightProperties "name","census_region_name" -Type AllInLeft ` 291 | | Invoke-UdfSQLDML -Mapping $mappingset -DmlOperation "Insert" -Destinationtablename "dbo.Customers" -connection $SqlServer1 -Verbose 292 | 293 | } 294 | 295 | function Invoke-UdfEmployeeLoad 296 | { 297 | 298 | # State Code List #> 299 | $global:referencepath = $env:HomeDrive + $env:HOMEPATH + "\Documents\" 300 | 301 | $employee = Import-CSV ($global:referencepath + "employees.txt") 302 | 303 | <# Define the mapping... #> 304 | $mappingset = @() # Create a collection object. 305 | $mappingset += (Add-UdfMapping "ID" "ID" "" $true) 306 | $mappingset += (Add-UdfMapping "Company" "Company" "'" $false) 307 | $mappingset += (Add-UdfMapping "First Name" "FirstName" "'" $false) 308 | $mappingset += (Add-UdfMapping "Last Name" "LastName" "'" $false) 309 | $mappingset += (Add-UdfMapping "Email Address" "EmailAddress" "'" $false) 310 | $mappingset += (Add-UdfMapping "Business Phone" "Phone" "'" $false) 311 | 312 | [psobject] $SqlServer1 = New-Object psobject 313 | New-UdfConnection ([ref]$SqlServer1) 314 | 315 | $SqlServer1.ConnectionType = 'ADO' 316 | $SqlServer1.DatabaseType = 'SqlServer' 317 | $SqlServer1.Server = '(local)' 318 | $SqlServer1.DatabaseName = 'Development' 319 | $SqlServer1.UseCredential = 'N' 320 | $SqlServer1.SetAuthenticationType('Integrated') 321 | $SqlServer1.BuildConnectionString() 322 | 323 | <# Clear the table... #> 324 | $SqlServer1.RunSQL("truncate table [dbo].[Employees]", $false) 325 | 326 | # Load the table… 327 | $employee | Invoke-UdfSQLDML -Mapping $mappingset -DmlOperation "Insert" -Destinationtablename "dbo.Employees" -connection $SqlServer1 –Verbose 328 | 329 | } 330 | 331 | # Invoke-UdfEmployeeLoad 332 | 333 | --------------------------------------------------------------------------------