valentia.psm1
#Requires -Version 3.0 Write-Verbose 'Loading valentia.psm1' # valentia # # Copyright (c) 2013 guitarrapc # # Permission is hereby granted, free of charge, to any person obtaining a copy # of this software and associated documentation files (the "Software"), to deal # in the Software without restriction, including without limitation the rights # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell # copies of the Software, and to permit persons to whom the Software is # furnished to do so, subject to the following conditions: # # The above copyright notice and this permission notice shall be included in # all copies or substantial portions of the Software. # # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN # THE SOFTWARE. #-- Public Loading Module Custom Configuration Functions --# function Import-ValentiaConfiguration { [CmdletBinding()] param ( [string]$OriginalConfigFilePath = (Join-Path $valentia.originalconfig.root $valentia.originalconfig.file), [string]$NewConfigFilePath = (Join-Path $valentia.appdataconfig.root $valentia.appdataconfig.file) ) if (Test-Path $OriginalConfigFilePath -pathType Leaf) { try { Write-Verbose $valeWarningMessages.warn_load_currentConfigurationOrDefault $config = Get-CurrentConfigurationOrDefault . $OriginalConfigFilePath return } catch { throw ('Error Loading Configuration from {0}: ' -f $OriginalConfigFilePath) + $_ } } } function Get-CurrentConfigurationOrDefault { [CmdletBinding()] param ( ) if ($valentia.context.count -gt 0) { return $valentia.context.peek().config } else { return $valentia.config_default } } function Import-ValentiaModules { [CmdletBinding()] param ( ) $currentConfig = $valentia.context.Peek().config if ($currentConfig.modules) { $currentConfig.modules | ForEach-Object { Resolve-Path $_ | ForEach-Object { "Loading module: $_" $module = Import-Module $_ -passthru -DisableNameChecking -global:$global if (!$module) { throw ($msgs.error_loading_module -f $_.Name) } } } '' # blank line for next entry } } #-- Private Loading Module Parameters --# # Setup Messages to be loaded DATA valeParamHelpMessages { ConvertFrom-StringData @' param_Get_ValentiaTask_Name = Input TaskName you want to set and not dupricated. param_Action = Write ScriptBlock Action to execute with this task. param_DeployGroups = Input target of deploy clients as [DeployGroup filename you sat at deploygroup Folder] or [ipaddress]. param_DeployFolder = Input DeployGroup Folder path if changed from default. param_TaskFileName = Move to Brach folder you sat taskfile, then input TaskFileName. exclusive with ScriptBlock. param_ScriptBlock = Input Script Block {hogehoge} you want to execute with this commandlet. exclusive with TaskFileName. param_quiet = Hide execution progress. param_ScriptToRun = Input ScriptBlock. ex) Get-ChildItem; Get-NetAdaptor | where MTUSize -gt 1400 param_wsmanSessionlimit = Input wsmanSession Threshold number to restart wsman param_Sessions = Input Session. param_RunspacePool = Runspace Poll required to set one or more, easy to create by New-ValentiaRunSpacePool. param_ScriptToRunHash = The scriptblock hashtable to be executed to the Remote host. param_DeployMember = Target Computers to execute scriptblock. param_credentialHash = Remote Login PSCredentail HashTable for PSRemoting. param_PoolSize = Defines the maximum number of pipelines that can be concurrently (asynchronously) executed on the pool. param_Pipelines = An array of Async Pipeline objects, returned by Invoke-ValentiaAsync. param_ShowProgress = An optional switch to display a progress indicator. param_Invoke_ValentiaUpload_SourcePath = Input Deploy Server SourcePath to be uploaded. param_Invoke_ValentiaUpload_DestinationPath = Input Clinet DestinationPath to save upload items. param_File = Set this switch to execute command for File. exclusive with Directory Switch. param_Directory = Set this switch to execute command for Directory. exclusive with File Switch. param_Async = Set this switch to execute command as Async (Job). param_ListFile = Input path defines source/destination of upload. param_Invoke_ValentiaSync_SourceFolder = Input Deploy Server Source Folder Sync to Client PC. param_Invoke_ValentiaSync_DestinationFolder = Input Client Destination Folder Sync with Desploy Server. param_FastCopyFolder = Input fastCopy.exe location folder if changed from default. param_FastcopyExe = Input fastCopy.exe name if changed from default. param_Invoke-ValentiaDownload_SourcePath = Input Client SourcePath to be downloaded. param_Invoke-ValentiaDownload_DestinationFolder = Input Server Destination Folder to save download items. param_Invoke-ValentiaDownload_force = Set this switch if you want to Force download. This will smbmap with source folder and Copy-Item -Force. (default is BitTransfer) '@ } # will be replace warning messages to StringData DATA valeWarningMessages { ConvertFrom-StringData @' warn_WinRM_session_exceed_nearly = WinRM session exceeded {0} and neerly limit of 25. Restarted WinRM on Remote Server to reset WinRM session. warn_WinRM_session_exceed_restarted = Restart Complete, trying remote session again. warn_WinRM_session_exceed_already = WinRM session is now {0}. It exceed {1} and neerly limit of 25. Restarting WinRM on Remote Server to reset WinRM session. warn_Stopwatch_showduration = ("`t`t{0}" warn_import_configuration = Importing Valentia Configuration. warn_import_modules = Importing Valentia modules. warn_import_task_begin = Importing Valentia task. warn_import_task_end = Task Load Complete. set task to lower case for keyname. warn_get_current_context = Get Current Context from valentia.context.peek(). warn_set_taskkey = Task key was new, set taskkey into current.context.taskkey. warn_load_currentConfigurationOrDefault = Load Current Configuration or Default. '@ } # will be replace error messages to StringData DATA valeErrorMessages { ConvertFrom-StringData @' error_invalid_task_name = Task name should not be null or empty string. error_task_name_does_not_exist = Task {0} does not exist. error_unknown_pointersize = Unknown pointer size ({0}) returned from System.IntPtr. error_bad_command = Error executing command {0}. error_default_task_cannot_have_action = 'default' task cannot specify an action. error_duplicate_task_name = Task {0} has already been defined. error_duplicate_alias_name = Alias {0} has already been defined. error_invalid_include_path = Unable to include {0}. File not found. error_build_file_not_found = Could not find the build file {0}. error_no_default_task = 'default' task required. '@ } # not yet ready but to resolve UI Culture for each country localization message. # Import-LocalizedData -BindingVariable messages -ErrorAction silentlycontinue #-- Private Loading Module Parameters --# # contains default base configuration, may not be override without version update. $Script:valentia = [ordered]@{} $valentia.name = 'valentia' $valentia.modulePath = Split-Path -parent $MyInvocation.MyCommand.Definition $valentia.helpersPath= '\functions\*' $valentia.typePath = '\type' $valentia.combineTempfunction = '{0}.ps1' -f $valentia.name $valentia.combineTemptype = 'Type.ps1' $valentia.cSharpPath = '\cs\' $valentia.supportWindows = @(6,1,0,0) # higher than windows 7 or windows 2008 R2 $valentia.fileEncode = [Microsoft.PowerShell.Commands.FileSystemCmdletProviderEncoding]'utf8' $valentia.context = New-Object System.Collections.Stack # Load Type from C# Enum $typePath = Join-Path $valentia.modulePath $valentia.combineTemptype if (Test-Path $typePath){ . $typePath } #region Load C# Class $valentia.CSharpPath = Join-Path $valentia.modulePath $valentia.cSharpPath -Resolve $valentia.CSharpParams = @( @{ # 1. Valentia.CS.PingAsync File = "PingAsync.cs" Assembly = "System", "System.Net", "System.Linq", "System.Threading.Tasks", "System.Net.NetworkInformation" }, @{ # 2. Valentia.CS.CredentialManager File = "CredentialManager.cs" Assembly = "System", "System.ComponentModel", "System.Management.Automation", "System.Runtime.InteropServices" }, @{ # 3. Valentia.CS.SymbolicLink File = "SymbolicLink.cs" Assembly = "System", "System.ComponentModel","System.Runtime.InteropServices" } ) foreach ($item in $valentia.CSharpParams.GetEnumerator()) { $private:csFullPath = Join-Path $valentia.CSharpPath $item.File -Resolve $private:csSource = Get-Content -Path $csFullPath -Raw Add-Type -TypeDefinition $csSource -ReferencedAssemblies $item.Assembly; } #endregion # contains default configuration path $valentia.originalconfig = [ordered]@{ root = Join-Path $valentia.modulePath '\config' file = '{0}-config.ps1' -f $valentia.name # default configuration file name to read } $valentia.appdataconfig = [ordered]@{ root = Join-Path $env:APPDATA $valentia.name # default configuration path file = '{0}-config.ps1' -f $valentia.name # default configuration file name to read } $valentia.appdataconfig.backup = Join-Path $valentia.appdataconfig.root '\config' # contains PS Build-in Preference status $valentia.preference = [ordered]@{ ErrorActionPreference = @{ original = $ErrorActionPreference custom = 'Stop' } DebugPreference = @{ original = $DebugPreference custom = 'SilentlyContinue' } VerbosePreference = @{ original = $VerbosePreference custom = 'SilentlyContinue' } ProgressPreference = @{ original = $ProgressPreference custom = 'SilentlyContinue' } } # contains WSman value to set by initialization $valentia.wsman = [PSCustomObject]@{ MaxShellsPerUser = 100; # default 25 change to 100 : "Configure WSMan MaxShellsPerUser to prevent error 'The WS-Management service cannot process the request. This user is allowed a maximum number of xx concurrent shells, which has been exceeded.'" MaxMemoryPerShellMB = 0; # default 1024 change to 0 means unlimited : "Configure WSMan MaxMBPerUser to prevent huge memory consumption crach PowerShell issue." MaxProccessesPerShell = 0; # default 100 change to 0 means unlimited : "Configure WSMan MaxProccessesPerShell to improve performance" TrustedHosts = "*"; } # contains CredSSP configuration $valentia.credssp = [PSCustomObject]@{ AllowFreshCredentialsWhenNTLMOnly = @{ Key = 'registry::hklm\SOFTWARE\Policies\Microsoft\Windows\CredentialsDelegation\AllowFreshCredentialsWhenNTLMOnly'; Value = ($valentia.wsman.TrustedHosts | %{"wsman/$_"}) -join ", "; } } # contains RunspacePoolExecution instance $valentia.runspace = [PSCustomObject]@{ # contains wait Limit settings for Asynchronous cmdlet (Invoke-ValentiaAsync) async = @{ sleepMS = 10; limitCount = 30000; } # contains instance of AsyncPipeline asyncPipeline = [System.Collections.Generic.List[AsyncPipeline]]; # contains RunSpace Pool Size for Asynchronous cmdlet (Invoke-ValentiaAsync) pool = @{ minSize = 1; maxSize = ([int]$env:NUMBER_OF_PROCESSORS * 30); instance = $null } } # contains ping property $valentia.ping = [PSCustomObject]@{ timeout = 10; buffer = 16; pingOption = @{ ttl = 64; dontFragment = $false; } } # Set Valentia prompt for choice messages $valentia.promptForChoice = [PSCustomObject]@{ title = 'Select item from prompt choices.'; questions = @('Yes', 'No'); defaultChoiceYes = 'y'; defaultChoiceNo = 'n'; helpMessage = "Enter '{0}' to select '{1}'." message = 'Type alphabet you want to choose.'; additionalMessage = $null; defaultIndex = 0; } # Set Valentia Log $valentia.log = [PSCustomObject]@{ path = "{0}\Logs\Deployment" -f $env:SystemDrive; name = "deploy"; extension = ".log"; dateformat= 'yyyyMMdd_HHmmss'; fullPath = ""; } #-- Public Loading Module Parameters (Recommend to use ($valentia.defaultconfigurationfile) for customization) --# # contains context for default. $valentia.context.push( @{ executedTasks = New-Object System.Collections.Stack; callStack = New-Object System.Collections.Stack; originalEnvPath = $env:Path; originalDirectory = Get-Location; originalErrorActionPreference = $valentia.preference.ErrorActionPreference.original; errorActionPreference = $valentia.preference.ErrorActionPreference.custom; originalDebugPreference = $valentia.preference.DebugPreference.original; debugPreference = $valentia.preference.DebugPreference.custom; originalProgressPreference = $valentia.preference.ProgressPreference.original; progressPreference = $valentia.preference.ProgressPreference.custom; name = $valentia.name; modulePath = $valentia.modulePath; helpersPath = Join-Path $valentia.modulePath $valentia.helpersPath; supportWindows = $valentia.supportWindows; fileEncode = $valentia.fileEncode; tasks = @{}; includes = New-Object System.Collections.Queue; Result = $valentia.Result; } ) # contains default OS user configuration $valentia.users = [PSCustomObject]@{ CurrentUser = $env:USERNAME; deployUser = "deployment"; } $valentia.group = [PSCustomObject]@{ name = "Administrators"; userFlag = "0X10040"; # #UserFlag for password (ex. infinity & No change Password) } # contains valentia execution policy for initial setup $valentia.ExecutionPolicy = [Microsoft.PowerShell.ExecutionPolicy]::Bypass # contains valentia remote invokation authentication mechanism $valentia.Authentication = [System.Management.Automation.Runspaces.AuthenticationMechanism]::Negotiate # contains valentia remote invokation SSL setting $valentia.UseSSL = $false # contains valentia configuration Information $valentia.PSDrive = "V:"; # Set Valentia Mapping Drive with SMBMapping $valentia.deployextension = ".ps1"; # contains default DeployGroup file extension # Define Prefix for Deploy Client NetBIOS name $valentia.prefix = New-Object psobject -property @{ hostName = "web"; ipstring = "ip"; } # contains default deployment Path configuration. $valentia.RootPath = "{0}\Deployment" -f $env:SystemDrive; # contains certificate configuration $valentia.certificate = [PSCustomObject]@{ ThumbPrint = "INPUT THUMBPRINT YOU WANT TO USE" CN = "dsc" # cer subject name you want to export from and import to FilePath = @{ Cert = Join-Path $valentia.originalconfig.root "\cert\{0}.cer" # cer save location PFX = Join-Path $valentia.originalconfig.root "\cert\{0}.pfx" # pfx save location } export = @{ CertStoreLocation = [System.Security.Cryptography.X509Certificates.StoreLocation]::LocalMachine # cer Store Location export from CertStoreName = [System.Security.Cryptography.X509Certificates.StoreName]::My # cer Store Name export from CertType = [System.Security.Cryptography.X509Certificates.X509ContentType]::Cert # export Type should be cert PFXType = [System.Security.Cryptography.X509Certificates.X509ContentType]::Pfx # export Type should be pfx } import = @{ CertStoreLocation = [System.Security.Cryptography.X509Certificates.StoreLocation]::LocalMachine # cer Store Location import to CertStoreName = [System.Security.Cryptography.X509Certificates.StoreName]::My # cer Store Name import to } Encrypt = @{ CertPath = "Cert:\LocalMachine\My" ThumbPrint = "INPUT THUMBPRINT YOU WANT TO USE" } } # Define External program path $valentia.fastcopy = [PSCustomObject]@{ folder = '{0}\lib\FastCopy.2.0.11.0\bin' -f $env:ChocolateyInstall; exe = 'FastCopy.exe'; } # contains default configuration, can be overriden in ($valentia.defaultconfigurationfile) in directory with valentia.psm1 or in directory with current task script $valentia.config_default = [PSCustomObject]([ordered]@{ TaskFileName = 'default.ps1'; Result = $valentia.Result TaskFileDir = [ValentiaBranchPath]::Application; taskNameFormat = 'Executing {0}'; verboseError = $false; modules = $null; PSDrive = $valentia.PSDrive; deployextension= $valentia.deployextension; prefix = $valentia.prefix; fastcopy = $valentia.fastcopy; RootPath = $valentia.RootPath; BranchFolder = [Enum]::GetNames([ValentiaBranchPath]); log = $valentia.log; }) #-- Set Alias for public valentia commands --# New-Alias -Name Task -Value Get-ValentiaTask New-Alias -Name Valep -Value Invoke-ValentiaParallel New-Alias -Name Vale -Value Invoke-Valentia New-Alias -Name Valea -Value Invoke-ValentiaAsync New-Alias -Name Upload -Value Invoke-ValentiaUpload New-Alias -Name UploadL -Value Invoke-ValentiaUploadList New-Alias -Name Sync -Value Invoke-ValentiaSync New-Alias -Name Download -Value Invoke-ValentiaDownload New-Alias -Name Go -Value Set-ValentiaLocation New-Alias -Name Clean -Value Invoke-ValentiaClean New-Alias -Name Target -Value Get-ValentiaGroup New-Alias -Name PingAsync -Value Ping-ValentiaGroupAsync New-Alias -Name Sed -Value Invoke-ValentiaSed New-Alias -Name IPRemark -Value Invoke-valentiaDeployGroupRemark New-Alias -Name IPUnremark -Value Invoke-valentiaDeployGroupUnremark New-Alias -Name Cred -Value Get-ValentiaCredential New-Alias -Name Rename -Value Set-ValentiaHostName New-Alias -Name DynamicParameter -Value New-ValentiaDynamicParamMulti New-Alias -Name Initial -Value Initialize-valentiaEnvironment #-- Loading Internal Function when loaded --# $outputPath = Join-Path $valentia.modulePath $valentia.combineTempfunction if (Test-Path $outputPath){ . $outputPath } #-- Loading External Configuration --# Import-ValentiaConfiguration Invoke-ValentiaCleanResult #-- Export Modules when loading this module --# Export-ModuleMember ` -Cmdlet * ` -Function * ` -Variable * ` -Alias * |