valentia.ps1
#Requires -Version 3.0 <# .SYNOPSIS Get ACL from selected source path. .DESCRIPTION You can get ACL information from selected source path. This is same logic as gACLResource. .NOTES Author: guitarrapc Created: 3/Sep/2014 .EXAMPLE Get-ValentiaACL -Path c:\Deployment -Account Users -------------------------------------------- Get ACL Information from c:\Deployment for user "Users", means no Computer/Domain user name checking. .EXAMPLE Get-ValentiaACL -Path c:\Deployment -Account contoso\John -------------------------------------------- Get ACL Information from c:\Deployment for user "contoso\John", means strict user name checking. .ExternalHelp "https://github.com/guitarrapc/DSCResources/tree/master/Custom/gACLResource" #> function Get-ValentiaACL { [CmdletBinding()] [OutputType([Hashtable])] param ( [Parameter(mandatory = $true, position = 0)] [ValidateNotNullOrEmpty()] [String]$Path, [Parameter(mandatory = $true, position = 1)] [ValidateNotNullOrEmpty()] [String]$Account, [Parameter(mandatory = $false, position = 2)] [ValidateNotNullOrEmpty()] [System.Security.AccessControl.FileSystemRights]$Rights = "ReadAndExecute", [Parameter(mandatory = $false, position = 3)] [ValidateSet("Present", "Absent")] [ValidateNotNullOrEmpty()] [String]$Ensure = "Present", [Parameter(mandatory = $false, position = 4)] [ValidateNotNullOrEmpty()] [ValidateSet("Allow", "Deny")] [System.Security.AccessControl.AccessControlType]$Access = "Allow", [Parameter(mandatory = $false, position = 5)] [Bool]$Inherit = $false, [Parameter(mandatory = $false, position = 6)] [Bool]$Recurse = $false, [Parameter(mandatory = $false, position = 7)] [Bool]$Strict = $false ) $desiredRule = GetDesiredRule -Path $Path -Account $Account -Rights $Rights -Access $Access -Inherit $Inherit -Recurse $Recurse $currentACL = (Get-Item $Path).GetAccessControl("Access") $currentRules = $currentACL.GetAccessRules($true, $true, [System.Security.Principal.NTAccount]) $match = IsDesiredRuleAndCurrentRuleSame -DesiredRule $desiredRule -CurrentRules $currentRules -Strict $Strict $presence = if ($true -eq $match) { "Present" } else { "Absent" } return @{ Ensure = $presence Path = $Path Account = $Account Rights = $Rights Access = $Access Inherit = $Inherit Recurse = $Recurse } } # file loaded from path : \functions\Helper\ACL\Get-ValentiaACL.ps1 #Requires -Version 3.0 <# .SYNOPSIS Set ACL from selected source path. .DESCRIPTION You can Set ACL information to selected source path. This is same logic as gACLResource. .NOTES Author: guitarrapc Created: 3/Sep/2014 .EXAMPLE Set-ValentiaACL -Path c:\Deployment -Account Users -Rights Modify -Ensure Present -Access Allow -Inherit $false -Recurse $false -------------------------------------------- Add FullControl to the c:\Deployment for user "Users", means no Computer/Domain user name checking. .EXAMPLE Set-ValentiaACL -Path c:\Deployment -Account contoso\John -Rights Modify -Ensure Present -Access Allow -Inherit $false -Recurse $false -------------------------------------------- Add FullControl to the c:\Deployment for user "BuiltIn\Users", means strict user name checking. .ExternalHelp "https://github.com/guitarrapc/DSCResources/tree/master/Custom/gACLResource" #> function Set-ValentiaACL { [CmdletBinding()] param ( [Parameter(mandatory = $true, position = 0)] [ValidateNotNullOrEmpty()] [String]$Path, [Parameter(mandatory = $true, position = 1)] [ValidateNotNullOrEmpty()] [String]$Account, [Parameter(mandatory = $false, position = 2)] [ValidateNotNullOrEmpty()] [System.Security.AccessControl.FileSystemRights]$Rights = "ReadAndExecute", [Parameter(mandatory = $false, position = 3)] [ValidateSet("Present", "Absent")] [ValidateNotNullOrEmpty()] [String]$Ensure = "Present", [Parameter(mandatory = $false, position = 4)] [ValidateNotNullOrEmpty()] [ValidateSet("Allow", "Deny")] [System.Security.AccessControl.AccessControlType]$Access = "Allow", [Parameter(mandatory = $false, position = 5)] [Bool]$Inherit = $false, [Parameter(mandatory = $false, position = 6)] [Bool]$Recurse = $false, [Parameter(mandatory = $false, position = 7)] [Bool]$Strict = $false ) $desiredRule = GetDesiredRule -Path $Path -Account $Account -Rights $Rights -Access $Access -Inherit $Inherit -Recurse $Recurse $currentACL = (Get-Item $Path).GetAccessControl("Access") $currentRules = $currentACL.GetAccessRules($true, $true, [System.Security.Principal.NTAccount]) $match = IsDesiredRuleAndCurrentRuleSame -DesiredRule $desiredRule -CurrentRules $currentRules -Strict $Strict if ($Ensure -eq "Present") { $CurrentACL.AddAccessRule($DesiredRule) $CurrentACL | Set-Acl -Path $Path } elseif ($Ensure -eq "Absent") { $CurrentACL.RemoveAccessRule($DesiredRule) > $null $CurrentACL | Set-Acl -Path $Path } } # file loaded from path : \functions\Helper\ACL\Set-ValentiaACL.ps1 #Requires -Version 3.0 <# .SYNOPSIS Test ACL from selected source path. .DESCRIPTION You can Test ACL information to selected source path. This is same logic as gACLResource. .NOTES Author: guitarrapc Created: 3/Sep/2014 .EXAMPLE Test-ValentiaACL -Path c:\Deployment -Account Users -Rights Modify -Ensure Present -Access Allow -Inherit $false -Recurse $false -------------------------------------------- TestACL to the c:\Deployment for user "Users", means no Computer/Domain user name checking. .EXAMPLE Test-ValentiaACL -Path c:\Deployment -Account contoso\John -Rights Modify -Ensure Present -Access Allow -Inherit $false -Recurse $false -------------------------------------------- TestACL to the c:\Deployment for user "contoso\John", means strict user name checking. .ExternalHelp "https://github.com/guitarrapc/DSCResources/tree/master/Custom/gACLResource" #> function Test-ValentiaACL { [CmdletBinding()] [OutputType([Boolean])] param ( [Parameter(mandatory = $true, position = 0)] [ValidateNotNullOrEmpty()] [String]$Path, [Parameter(mandatory = $true, position = 1)] [ValidateNotNullOrEmpty()] [String]$Account, [Parameter(mandatory = $false, position = 2)] [ValidateNotNullOrEmpty()] [System.Security.AccessControl.FileSystemRights]$Rights = "ReadAndExecute", [Parameter(mandatory = $false, position = 3)] [ValidateSet("Present", "Absent")] [ValidateNotNullOrEmpty()] [String]$Ensure = "Present", [Parameter(mandatory = $false, position = 4)] [ValidateNotNullOrEmpty()] [ValidateSet("Allow", "Deny")] [System.Security.AccessControl.AccessControlType]$Access = "Allow", [Parameter(mandatory = $false, position = 5)] [Bool]$Inherit = $false, [Parameter(mandatory = $false, position = 6)] [Bool]$Recurse = $false, [Parameter(mandatory = $false, position = 7)] [Bool]$Strict = $false ) $desiredRule = GetDesiredRule -Path $Path -Account $Account -Rights $Rights -Access $Access -Inherit $Inherit -Recurse $Recurse $currentACL = (Get-Item $Path).GetAccessControl("Access") $currentRules = $currentACL.GetAccessRules($true, $true, [System.Security.Principal.NTAccount]) $match = IsDesiredRuleAndCurrentRuleSame -DesiredRule $desiredRule -CurrentRules $currentRules -Strict $Strict $presence = if ($true -eq $match) { "Present" } else { "Absent" } return $presence -eq $Ensure } # file loaded from path : \functions\Helper\ACL\Test-ValentiaACL.ps1 #Requires -Version 3.0 function GetDesiredRule { [OutputType([System.Security.AccessControl.FileSystemAccessRule])] [CmdletBinding()] param ( [Parameter(mandatory = $true)] [ValidateNotNullOrEmpty()] [String]$Path, [Parameter(mandatory = $true)] [ValidateNotNullOrEmpty()] [String]$Account, [Parameter(mandatory = $false)] [ValidateNotNullOrEmpty()] [System.Security.AccessControl.FileSystemRights]$Rights = "ReadAndExecute", [Parameter(mandatory = $false)] [ValidateNotNullOrEmpty()] [System.Security.AccessControl.AccessControlType]$Access = "Allow", [Parameter(mandatory = $false)] [Bool]$Inherit = $false, [Parameter(mandatory = $false)] [Bool]$Recurse = $false ) $InheritFlag = if ($Inherit) { "{0}, {1}" -f [System.Security.AccessControl.InheritanceFlags]::ContainerInherit, [System.Security.AccessControl.InheritanceFlags]::ObjectInherit } elseif ($Recurse) { "{0}, {1}" -f [System.Security.AccessControl.InheritanceFlags]::ContainerInherit, [System.Security.AccessControl.InheritanceFlags]::ObjectInherit } else { [System.Security.AccessControl.InheritanceFlags]::None } $desiredRule = New-Object System.Security.AccessControl.FileSystemAccessRule($Account, $Rights, $InheritFlag, "None", $Access) return $desiredRule } # file loaded from path : \functions\Helper\ACL\Private\GetDesiredRule.ps1 #Requires -Version 3.0 function IsDesiredRuleAndCurrentRuleSame { [OutputType([Bool])] [CmdletBinding()] param ( [System.Security.AccessControl.FileSystemAccessRule]$DesiredRule, [System.Security.AccessControl.AuthorizationRuleCollection]$CurrentRules, [bool]$Strict ) $match = if ($Strict) { Write-Verbose "Using strict name checking. It does not split AccountName with \''." $currentRules ` | where {$_.IdentityReference.Value -eq $DesiredRule.IdentityReference.Value} ` | where FileSystemRights -eq $DesiredRule.FileSystemRights ` | where AccessControlType -eq $DesiredRule.AccessControlType ` | where Inherit -eq $_.InheritanceFlags ` | measure } else { Write-Verbose "Using non-strict name checking. It split AccountName with \''." $currentRules ` | where {$_.IdentityReference.Value.Split("\")[1] -eq $DesiredRule.IdentityReference.Value} ` | where FileSystemRights -eq $DesiredRule.FileSystemRights ` | where AccessControlType -eq $DesiredRule.AccessControlType ` | where Inherit -eq $_.InheritanceFlags ` | measure } if ($match.Count -eq 0) { Write-Verbose "Current ACL result." Write-Verbose ($CurrentRules | Format-List | Out-String) Write-Verbose "Desired ACL result." Write-Verbose ($DesiredRule | Format-List | Out-String) Write-Verbose "Result does not match as desired. Showing Desired v.s. Current Status." [PSCustomObject]@{ DesiredRuleIdentity = $DesiredRule.IdentityReference.Value CurrentRuleIdentity = $currentRules.IdentityReference.Value StrictCurrentRuleIdentity = $currentRules.IdentityReference.Value.Split("\")[1] StrictResult = ($currentRules | where {$_.IdentityReference.Value -eq $DesiredRule.IdentityReference.Value} | measure).Count -ne 0 NoneStrictResult = ($currentRules | where {$_.IdentityReference.Value.Split("\")[1] -eq $DesiredRule.IdentityReference.Value} | measure).Count -ne 0 } | Format-List | Out-String -Stream | Write-Verbose [PSCustomObject]@{ DesiredFileSystemRights = $DesiredRule.FileSystemRights CurrentFileSystemRights = $currentRules.FileSystemRights StrictResult = ($currentRules | where {$_.IdentityReference.Value -eq $DesiredRule.IdentityReference.Value} | where FileSystemRights -eq $DesiredRule.FileSystemRights | measure).Count -ne 0 NoneStrictResult = ($currentRules | where {$_.IdentityReference.Value.Split("\")[1] -eq $DesiredRule.IdentityReference.Value} | where FileSystemRights -eq $DesiredRule.FileSystemRights | measure).Count -ne 0 } | Format-List | Out-String -Stream | Write-Verbose [PSCustomObject]@{ DesiredAccessControlType = $DesiredRule.AccessControlType CurrentAccessControlType = $currentRules.AccessControlType StrictResult = ($currentRules | where {$_.IdentityReference.Value -eq $DesiredRule.IdentityReference.Value} | where FileSystemRights -eq $DesiredRule.FileSystemRights | where AccessControlType -eq $DesiredRule.AccessControlType | measure).Count -ne 0 NoneStrictResult = ($currentRules | where {$_.IdentityReference.Value.Split("\")[1] -eq $DesiredRule.IdentityReference.Value} | where FileSystemRights -eq $DesiredRule.FileSystemRights | where AccessControlType -eq $DesiredRule.AccessControlType | measure).Count -ne 0 } | Format-List | Out-String -Stream | Write-Verbose [PSCustomObject]@{ DesiredInherit = $DesiredRule.Inherit CurrentInherit = $currentRules.Inherit StrictResult = ($currentRules | where {$_.IdentityReference.Value -eq $DesiredRule.IdentityReference.Value} | where FileSystemRights -eq $DesiredRule.FileSystemRights | where AccessControlType -eq $DesiredRule.AccessControlType | where Inherit -eq $DesiredRule.Inherit | measure).Count -ne 0 NoneStrictResult = ($currentRules | where {$_.IdentityReference.Value.Split("\")[1] -eq $DesiredRule.IdentityReference.Value} | where FileSystemRights -eq $DesiredRule.FileSystemRights | where AccessControlType -eq $DesiredRule.AccessControlType | where Inherit -eq $DesiredRule.Inherit | measure).Count -ne 0 } | Format-List | Out-String -Stream | Write-Verbose } return $match.Count -ge 1 } # file loaded from path : \functions\Helper\ACL\Private\IsDesiredRuleAndCurrentRuleSame.ps1 #Requires -Version 3.0 #-- Helper for certificate --# function Convert-ValentiaDecryptPassword { param ( [parameter(mandatory = $true, position = 0, ValueFromPipeline = 1, ValueFromPipelineByPropertyName = 1)] [ValidateNotNullOrEmpty()] [string]$EncryptedKey, [parameter(mandatory = $false, position = 1, ValueFromPipelineByPropertyName = 1)] [ValidateNotNullOrEmpty()] [string]$thumbprint = $valentia.certificate.Encrypt.ThumbPrint, [parameter(mandatory = $false, position = 1, ValueFromPipelineByPropertyName = 1)] [ValidateNotNullOrEmpty()] [string]$certPath = $valentia.certificate.Encrypt.CertPath ) process { $EnvelopedCms = New-Object Security.Cryptography.Pkcs.EnvelopedCms $EnvelopedCms.Decode([convert]::FromBase64String($EncryptedKey)) $EnvelopedCms.Decrypt($Cert) [Text.Encoding]::UTF8.GetString($EnvelopedCms.ContentInfo.Content) } begin { try { Add-type –AssemblyName System.Security } catch { } $Path = Join-Path $certPath $thumbprint if (Test-Path $Path) { $Cert = Get-Item $Path } else { Write-Warning ("Certification not found exception!! Cert: '{0}'" -f $Path) } } } # file loaded from path : \functions\Helper\Certificate\Convert-ValentiaDecryptPassword .ps1 #Requires -Version 3.0 #-- Helper for certificate --# function Convert-ValentiaEncryptPassword { param ( [parameter(mandatory = $true, position = 0, ValueFromPipeline = 1, ValueFromPipelineByPropertyName = 1)] [ValidateNotNullOrEmpty()] [pscredential[]]$Credential, [parameter(mandatory = $false, position = 1, ValueFromPipelineByPropertyName = 1)] [ValidateNotNullOrEmpty()] [string]$thumbprint = $valentia.certificate.Encrypt.ThumbPrint, [parameter(mandatory = $false, position = 1, ValueFromPipelineByPropertyName = 1)] [ValidateNotNullOrEmpty()] [string]$certPath = $valentia.certificate.Encrypt.CertPath ) process { foreach ($cred in $Credential) { $passwordByte = [Text.Encoding]::UTF8.GetBytes($Cred.GetNetworkCredential().Password) $contentInfo = New-Object Security.Cryptography.Pkcs.ContentInfo @(,$passwordByte) $EnvelopedCms = New-Object Security.Cryptography.Pkcs.EnvelopedCms $contentInfo $EnvelopedCms.Encrypt((New-Object System.Security.Cryptography.Pkcs.CmsRecipient($Cert))) [Convert]::ToBase64String($EnvelopedCms.Encode()) } } begin { try { Add-type –AssemblyName System.Security } catch { } $Path = Join-Path $certPath $thumbprint if (Test-Path $Path) { $Cert = Get-Item $Path } else { Write-Warning ("Certification not found exception!! Cert: '{0}'" -f $Path) } } } # file loaded from path : \functions\Helper\Certificate\Convert-ValentiaEncryptPassword .ps1 #Requires -Version 3.0 #-- Helper for certificate --# function Export-ValentiaCertificate { [CmdletBinding()] param ( [parameter(mandatory = $true, position = 0, ValueFromPipeline = 1, ValueFromPipelineByPropertyName = 1)] [ValidateNotNullOrEmpty()] [System.Security.Cryptography.X509Certificates.X509Certificate2]$cert, [parameter(mandatory = $false, position = 1)] [ValidateNotNullOrEmpty()] [string]$CN = $valentia.certificate.CN, [parameter(mandatory = $false, position = 2)] [ValidateNotNullOrEmpty()] [string]$exportFilePath = $valentia.certificate.FilePath.Cert, [parameter(mandatory = $false, position = 3)] [ValidateNotNullOrEmpty()] [System.Security.Cryptography.X509Certificates.X509ContentType]$certType = $valentia.certificate.export.CertType ) process { "Export cert '{0}' to '{1}'." -f $cert.ThumbPrint ,$FilePath | Write-ValentiaVerboseDebug $certToExportInBytes = $cert.Export($certType) [System.IO.File]::WriteAllBytes($FilePath, $certToExportInBytes) } begin { "Export Path setup." | Write-ValentiaVerboseDebug $FilePath = $exportFilePath -f $CN $dir = Split-Path $FilePath -Parent if (-not (Test-Path $dir)) { New-Item -Path $dir -ItemType Directory -Force } elseif (Test-Path $FilePath) { Remove-Item -Path $FilePath -Confirm -Force } if (Test-Path $FilePath) { throw "Certificate already exist in '{0}'. Make sure you have delete exist cert before export." -f $FilePath } } end { Get-Item $FilePath } } # file loaded from path : \functions\Helper\Certificate\Export-ValentiaCertificate.ps1 #Requires -Version 3.0 #-- Helper for certificate --# function Export-ValentiaCertificatePFX { [CmdletBinding()] param ( [parameter(mandatory = $true, position = 0, ValueFromPipeline = 1, ValueFromPipelineByPropertyName = 1)] [ValidateNotNullOrEmpty()] [System.Security.Cryptography.X509Certificates.X509Certificate2]$pfx, [parameter(mandatory = $false, position = 1)] [ValidateNotNullOrEmpty()] [string]$CN = $valentia.certificate.CN, [parameter(mandatory = $false, position = 2)] [ValidateNotNullOrEmpty()] [string]$exportFilePath = $valentia.certificate.FilePath.PFX, [parameter(mandatory = $false, position = 3)] [ValidateNotNullOrEmpty()] [System.Security.Cryptography.X509Certificates.X509ContentType]$PFXType = $valentia.certificate.export.PFXType, [parameter(mandatory = $false, position = 4)] [ValidateNotNullOrEmpty()] [PSCredential]$Credential = $null ) process { "Export pfx '{0}' as object." -f $cert.ThumbPrint | Write-ValentiaVerboseDebug $pfxToExportInBytes = $pfx.Export($PFXType, $credential.GetNetworkCredential().Password) [System.IO.File]::WriteAllBytes($FilePath, $pfxToExportInBytes) } begin { "Export Path setup." | Write-ValentiaVerboseDebug $FilePath = $exportFilePath -f $CN $dir = Split-Path $FilePath -Parent if (-not (Test-Path $dir)) { New-Item -Path $dir -ItemType Directory -Force } elseif (Test-Path $FilePath) { Remove-Item -Path $FilePath -Confirm -Force } "Get pfx password to export." | Write-ValentiaVerboseDebug if ($null -eq $Credential) { $credential = Get-Credential -Credential "INPUT Password FOR PFX export." } if (Test-Path $FilePath) { throw "Certificate already exist in '{0}'. Make sure you have delete exist cert before export." -f $FilePath } } } # file loaded from path : \functions\Helper\Certificate\Export-ValentiaCertificatePFX.ps1 #Requires -Version 3.0 #-- Helper for certificate --# function Get-ValentiaCertificateFromCert { [CmdletBinding()] param ( [parameter(mandatory = $false, position = 0)] [ValidateNotNullOrEmpty()] [string]$CN = $valentia.certificate.CN, [parameter(mandatory = $false, position = 1)] [ValidateNotNullOrEmpty()] [System.Security.Cryptography.X509Certificates.StoreLocation]$certStoreLocation = $valentia.certificate.export.CertStoreLocation, [parameter(mandatory = $false, position = 2)] [ValidateNotNullOrEmpty()] [System.Security.Cryptography.X509Certificates.StoreName]$certStoreName = $valentia.certificate.export.CertStoreName ) "Obtain Cert from CertStoreLocation." | Write-ValentiaVerboseDebug $certStoreLocationPath = Join-Path "cert:" $certStoreLocation -Resolve $certStoreFullPath = Join-Path $certStoreLocationPath $certStoreName -Resolve $cert = (Get-ChildItem $certStoreFullPath | where Subject -eq "CN=$cn") | select -First 1 if ($null -eq $cert) { throw "Certificate for CN '{0}' not found." -f $CN } return [System.Security.Cryptography.X509Certificates.X509Certificate2]$cert } # file loaded from path : \functions\Helper\Certificate\Get-ValentiaCertificateFromCert.ps1 #Requires -Version 3.0 #-- Helper for certificate --# function Import-ValentiaCertificate { [CmdletBinding()] param ( [parameter(mandatory = $false, position = 0)] [ValidateNotNullOrEmpty()] [string]$CN = $valentia.certificate.CN, [parameter(mandatory = $false, position = 1)] [ValidateNotNullOrEmpty()] [System.Security.Cryptography.X509Certificates.StoreLocation]$certStoreLocation = $valentia.certificate.import.CertStoreLocation, [parameter(mandatory = $false, position = 2)] [ValidateNotNullOrEmpty()] [System.Security.Cryptography.X509Certificates.StoreName]$certStoreName = $valentia.certificate.import.CertStoreName, [parameter(mandatory = $false, position = 3, ValueFromPipeline = 1, ValueFromPipelineByPropertyName = 1)] [ValidateNotNullOrEmpty()] [string]$importFilePath = $valentia.certificate.FilePath.Cert ) process { try { "Import certificate '{0}' to CertStore '{1}'" -f $FilePath, (Get-Item ("cert:{0}\{1}" -f $certStore.Location, $certStore.Name)).PSPath | Write-ValentiaVerboseDebug $CertStore.Open([System.Security.Cryptography.X509Certificates.OpenFlags]::MaxAllowed) $CertStore.Add($CertToImport) } finally { $CertStore.Close() } } begin { "obtain cert." | Write-ValentiaVerboseDebug $FilePath = ($importFilePath -f $CN) if (-not (Test-Path $FilePath)) { throw "Certificate not found in '{0}'. Make sure you have been already exported." -f $FilePath } if ($certStoreLocation -eq [System.Security.Cryptography.X509Certificates.StoreLocation]::LocalMachine) { if(-not(Test-ValentiaPowerShellElevated)) { throw "Your PowerShell Console is not elevated! Must start PowerShell as an elevated to run this function because of UAC." } else { "Current session is already elevated, continue setup environment." | Write-ValentiaVerboseDebug } } "Cert identification." | Write-ValentiaVerboseDebug $flags = [System.Security.Cryptography.X509Certificates.X509KeyStorageFlags]::MachineKeySet -bor [System.Security.Cryptography.X509Certificates.X509KeyStorageFlags]::PersistKeySet $CertToImport = New-Object System.Security.Cryptography.X509Certificates.X509Certificate2 $FilePath, "", $flags $CertStore = New-Object System.Security.Cryptography.X509Certificates.X509Store $CertStoreName, $CertStoreLocation } } # file loaded from path : \functions\Helper\Certificate\Import-ValentiaCertificate.ps1 #Requires -Version 3.0 #-- Helper for certificate --# function Import-ValentiaCertificatePFX { [CmdletBinding()] param ( [parameter(mandatory = $false, position = 0)] [ValidateNotNullOrEmpty()] [string]$CN = $valentia.certificate.CN, [parameter(mandatory = $false, position = 1)] [ValidateNotNullOrEmpty()] [System.Security.Cryptography.X509Certificates.StoreLocation]$certStoreLocation = $valentia.certificate.import.CertStoreLocation, [parameter(mandatory = $false, position = 2)] [ValidateNotNullOrEmpty()] [System.Security.Cryptography.X509Certificates.StoreName]$certStoreName = $valentia.certificate.import.CertStoreName, [parameter(mandatory = $false, position = 3, ValueFromPipeline = 1, ValueFromPipelineByPropertyName = 1)] [ValidateNotNullOrEmpty()] [string]$importFilePath = $valentia.certificate.FilePath.PFX, [parameter(mandatory = $false, position = 4)] [ValidateNotNullOrEmpty()] [PSCredential]$Credential = $null ) process { try { "Import certificate PFX '{0}' to CertStore '{1}'" -f $FilePath, (Get-Item ("cert:{0}\{1}" -f $certStore.Location, $certStore.Name)).PSPath | Write-ValentiaVerboseDebug $PFXStore.Open([System.Security.Cryptography.X509Certificates.OpenFlags]::MaxAllowed) $PFXStore.Add($PFXToImport) } finally { $PFXStore.Close() } } begin { "obtain pfx." | Write-ValentiaVerboseDebug $FilePath = ($importFilePath -f $CN) if (-not (Test-Path $FilePath)) { throw "Certificate not found in '{0}'. Make sure you have been already exported." -f $FilePath } if ($certStoreLocation -eq [System.Security.Cryptography.X509Certificates.StoreLocation]::LocalMachine) { if(-not(Test-ValentiaPowerShellElevated)) { throw "Your PowerShell Console is not elevated! Must start PowerShell as an elevated to run this function because of UAC." } else { "Current session is already elevated, continue setup environment." | Write-ValentiaVerboseDebug } } "Get pfx password to export." | Write-ValentiaVerboseDebug if ($null -eq $Credential) { $credential = Get-Credential -Credential "INPUT Password FOR PFX export." } "PFX identification." | Write-ValentiaVerboseDebug $flags = [System.Security.Cryptography.X509Certificates.X509KeyStorageFlags]::MachineKeySet -bor [System.Security.Cryptography.X509Certificates.X509KeyStorageFlags]::PersistKeySet $PFXToImport = New-Object System.Security.Cryptography.X509Certificates.X509Certificate2 $FilePath, $credential.GetNetworkCredential().Password, $flags $PFXStore = New-Object System.Security.Cryptography.X509Certificates.X509Store $CertStoreName, $CertStoreLocation } } # file loaded from path : \functions\Helper\Certificate\Import-ValentiaCertificatePFX.ps1 #Requires -Version 3.0 #-- Helper for certificate --# function Remove-ValentiaCertificate { [CmdletBinding()] param ( [parameter(mandatory = $false, position = 0)] [ValidateNotNullOrEmpty()] [string]$CN = $valentia.certificate.CN, [parameter(mandatory = $false, position = 1, ValueFromPipeline = 1, ValueFromPipelineByPropertyName = 1)] [ValidateNotNullOrEmpty()] [string]$CertFilePath = $valentia.certificate.FilePath.Cert, [parameter(mandatory = $false, position = 2)] [switch]$force = $false ) $param = @{ Path = $CertFilePath -f $CN Confirm = (-not $force) Force = $force } if (Test-Path $param.Path) { Remove-Item @param } } # file loaded from path : \functions\Helper\Certificate\Remove-ValentiaCertificate.ps1 #Requires -Version 3.0 #-- Helper for certificate --# function Remove-ValentiaCertificatePFX { [CmdletBinding()] param ( [parameter(mandatory = $false, position = 0)] [ValidateNotNullOrEmpty()] [string]$CN = $valentia.certificate.CN, [parameter(mandatory = $false, position = 1, ValueFromPipeline = 1, ValueFromPipelineByPropertyName = 1)] [ValidateNotNullOrEmpty()] [string]$PFXFilePath = $valentia.certificate.FilePath.PFX, [parameter(mandatory = $false, position = 2)] [switch]$force = $false ) $param = @{ Path = $PFXFilePath -f $CN Confirm = (-not $force) Force = $force } if (Test-Path $param.Path) { Remove-Item @param } } # file loaded from path : \functions\Helper\Certificate\Remove-ValentiaCertificatePFX.ps1 #Requires -Version 3.0 #-- Helper for certificate --# function Show-ValentiaCertificate { [CmdletBinding()] param ( [parameter(mandatory = $false, position = 0)] [ValidateNotNullOrEmpty()] [string]$CN = $valentia.certificate.CN, [parameter(mandatory = $false,position = 1)] [ValidateNotNullOrEmpty()] [System.Security.Cryptography.X509Certificates.StoreLocation]$certStoreLocationExport = $valentia.certificate.export.CertStoreLocation, [parameter(mandatory = $false, position = 2)] [ValidateNotNullOrEmpty()] [System.Security.Cryptography.X509Certificates.StoreName]$certStoreNameExport = $valentia.certificate.export.CertStoreName, [parameter(mandatory = $false, position = 3)] [ValidateNotNullOrEmpty()] [System.Security.Cryptography.X509Certificates.StoreLocation]$certStoreLocationImport = $valentia.certificate.import.CertStoreLocation, [parameter(mandatory = $false, position = 4)] [ValidateNotNullOrEmpty()] [System.Security.Cryptography.X509Certificates.StoreName]$certStoreNameImport = $valentia.certificate.import.CertStoreName, [parameter(mandatory = $false, position = 5)] [ValidateNotNullOrEmpty()] [string]$CertFilePath = $valentia.certificate.FilePath.Cert, [parameter(mandatory = $false, position = 6)] [ValidateNotNullOrEmpty()] [string]$PFXFilePath = $valentia.certificate.FilePath.PFX ) "Obtain CERT from export CertStoreLocation." | Write-ValentiaVerboseDebug $certExport = Get-ValentiaCertificateFromCert if ($null -eq $certExport) { Write-Warning ("Certificate for CN '{0}' not found." -f $CN) } "Obtain CERT from Import CertStoreLocation." | Write-ValentiaVerboseDebug $certStoreLocationPathImport= Join-Path "cert:" $certStoreLocationImport -Resolve $certStoreFullPathImport = Join-Path $certStoreLocationPathImport $certStoreNameImport -Resolve $certImport = (Get-ChildItem $certStoreFullPathImport | where Subject -eq "CN=$cn") | select -First 1 if ($null -eq $certImport) { Write-Warning ("Certificate for CN '{0}' not found." -f $CN) } "Obtain Cer file." | Write-ValentiaVerboseDebug $certPath = $CertFilePath -f $CN if (Test-Path $certPath) { $certFile = Get-Item $certPath } else { Write-Warning ("Certificate file not found '{0}'." -f $certPath) } "Obtain PFX file." | Write-ValentiaVerboseDebug $pfxPath = $PFXFilePath -f $CN if (Test-Path $pfxPath) { $pfxFile = Get-Item $pfxPath } else { Write-Warning ("PFX file not found '{0}'." -f $pfxPath) } return [PSCustomObject]@{ ExportCert = $certExport ImportCert = $certImport CertFile = $certFile PFXFile = $pfxFile } } # file loaded from path : \functions\Helper\Certificate\Show-ValentiaCertificate.ps1 #Requires -Version 3.0 #-- Helper for valentia --# # clean <# .SYNOPSIS Clean up valentia task variables. .DESCRIPTION Clear valentia variables for each task, and remove then. valentia only keep default variables after this cmdlet has been run. .NOTES Author: guitarrapc Created: 13/Jul/2013 .EXAMPLE Invoke-ValentiaClean -------------------------------------------- Clean up valentia variables stacked in the $valentia variables. #> function Invoke-ValentiaClean { [CmdletBinding()] param ( ) if ($valentia.context.Count -gt 0) { $currentContext = $valentia.context.Peek() $env:path = $currentContext.originalEnvPath Set-Location $currentContext.originalDirectory $global:ErrorActionPreference = $currentContext.originalErrorActionPreference # Erase Context [void] $valentia.context.Clear() } } # file loaded from path : \functions\Helper\CleanupVariables\Invoke-ValentiaClean.ps1 #Requires -Version 3.0 #-- Helper for valentia --# # cleanResult <# .SYNOPSIS Clean up valentia task previous result. .DESCRIPTION Clear valentia last result. .NOTES Author: guitarrapc Created: 13/Jul/2013 .EXAMPLE Invoke-ValentiaCleanResult #> function Invoke-ValentiaCleanResult { [CmdletBinding()] param ( ) $valentia.Result = [ordered]@{ SuccessStatus = @() TimeStart = [datetime]::Now.DateTime ScriptToRun = "" DeployMembers = @() Result = New-Object 'System.Collections.Generic.List[PSCustomObject]' ErrorMessageDetail = @() } } # file loaded from path : \functions\Helper\CleanupVariables\Invoke-ValentiaCleanResult.ps1 #Requires -Version 3.0 function Get-ValentiaComputerName { [CmdletBinding(DefaultParameterSetName = 'Registry')] param ( [parameter(mandatory = $false, Position = 0, ParameterSetName = "Registry")] [switch]$Registry, [parameter(mandatory = $false, Position = 0, ParameterSetName = "DotNet")] [switch]$DotNet ) end { if ($DotNet) { Write-Verbose "Objain Host Names from Syste.Net.DSC." $hostByName = [System.Net.DNS]::GetHostByName('') [PSCustomObject]@{ HostaName = $hostByName.HostName IPAddress = $hostByName.AddressList } } else { $RegistryParam.GetEnumerator() | %{CheckItemProperty -BasePath $_.BasePath -name $_.Name} } } begin { Set-StrictMode -Version Latest # HostName from Refistry Write-Verbose "Obtain Host Names from Registry Keys." $HKLMComputerName = "registry::HKLM\SYSTEM\CurrentControlSet\Control\Computername" $HKLMTcpip = "registry::HKLM\SYSTEM\CurrentControlSet\Services\Tcpip\Parameters" $HKLMWinLogon = "registry::HKLM\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Winlogon" $HKUWMSDK = "registry::HKU\.Default\Software\Microsoft\Windows Media\WMSDK\General" $RegistryParam = ( @{ BasePath = "$HKLMComputerName\Computername" name ="Computername" }, @{ BasePath = "$HKLMComputerName\ActiveComputername" name ="Computername" }, @{ BasePath = $HKLMTcpip name = "Hostname" }, @{ BasePath = $HKLMTcpip name = "NV Hostname" }, @{ BasePath = $HKLMWinLogon name = "AltDefaultDomainName" }, @{ BasePath = $HKLMWinLogon name = "DefaultDomainName" }, @{ BasePath = $HKUWMSDK name = "Computername" } ) function CheckItemProperty ([string]$BasePath, [string]$Name) { $result = $null if (Test-Path $BasePath) { $base = Get-ItemProperty $BasePath $keyExist = ($base | Get-Member -MemberType NoteProperty).Name -contains $Name if (($null -ne $base) -and $keyExist) { Write-Verbose ("Found. Path '{0}' and Name '{1}' found. Show result." -f $BasePath, $Name) $result = [ordered]@{ path = $BasePath Property = $name value = ($base | where $Name | %{Get-ItemProperty -path $BasePath -name $Name}).$Name } } else { Write-Verbose ("Skip. Path '{0}' found but Name '{1}' not found." -f $BasePath, $Name) } } else { Write-Verbose ("Skip. Path '{0}' not found." -f $BasePath) } if ($null -eq $result) { Write-Verbose ("Skip. Item Property '{0}' not found from path '{1}'." -f $name, $BasePath) } else { return [PSCustomObject]$result } } } } # file loaded from path : \functions\Helper\ComputerName\Get-ValentiaComputerName.ps1 #Requires -Version 3.0 #-- Helper for valentia --# function Rename-ValentiaComputerName { [CmdletBinding(SupportsShouldProcess = $true, ConfirmImpact = 'High')] param ( [parameter(mandatory = $true, Position = 0, ValueFromPipeline = 1, ValueFromPipelineByPropertyName = 1)] [validateLength(1,15)] [string]$NewComputerName, [parameter(mandatory = $false, Position = 1)] [switch]$Force, [parameter(mandatory = $false, Position = 2)] [switch]$PassThru = $false ) end { # InvalidCharactorCheck if ($detect = GetContainsInvalidCharactor -ComputerName $NewComputerName) { throw ("NewComputerName '{0}' conrains invalid charactor : {1} . Make sure not to include following fault charactors. : {2}" -f $NewComputerName, (($detect | sort -Unique) -join ""), '`~!@#$%^&*()=+_[]{}\|;:.''",<>/?') } # Execute Change $RegistryParam.GetEnumerator() ` | %{CheckItemProperty -BasePath $_.BasePath -name $_.Name} ` | where {$force -or $PSCmdlet.ShouldProcess($_.path, ("Change ComputerName on Registry PropertyName : '{1}', CurrentValue : '{2}', NewName : '{3}'" -f $_.path, $_.Property, $_.Value, $NewComputerName))} ` | %{ if ($_.Path -eq $HKLMTcpip) { Write-Verbose ("Removing existing Registry before set new ComputerName. Registry : '{0}'" -f $_.path) Remove-ItemProperty -Path $_.path -Name $_.Property } Write-Verbose ("Setting New ComputerName on Registry : '{0}'" -f $_.path) Set-ItemProperty -Path $_.path -Name $_.Property -Value $NewComputerName -PassThru:$passThru } } begin { Set-StrictMode -Version Latest $PSBoundParameters.Remove('Force') > $null $list = New-Object 'System.Collections.Generic.List[PSCustomObject]' # HostName from Refistry Write-Verbose "Obtain Host Names from Registry Keys." $HKLMComputerName = "registry::HKLM\SYSTEM\CurrentControlSet\Control\Computername" $HKLMTcpip = "registry::HKLM\SYSTEM\CurrentControlSet\Services\Tcpip\Parameters" $HKLMWinLogon = "registry::HKLM\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Winlogon" $HKUWMSDK = "registry::HKU\.Default\Software\Microsoft\Windows Media\WMSDK\General" $RegistryParam = ( @{ BasePath = "$HKLMComputerName\Computername" name ="Computername" }, @{ BasePath = "$HKLMComputerName\ActiveComputername" name ="Computername" }, @{ BasePath = $HKLMTcpip name = "Hostname" }, @{ BasePath = $HKLMTcpip name = "NV Hostname" }, @{ BasePath = $HKLMWinLogon name = "AltDefaultDomainName" }, @{ BasePath = $HKLMWinLogon name = "DefaultDomainName" }, @{ BasePath = $HKUWMSDK name = "Computername" } ) function GetContainsInvalidCharactor ([string]$ComputerName) { $detectedChar = "" # Invalid Charactor list described by MS : http://support.microsoft.com/kb/228275 $invalidCharactor = [System.Linq.Enumerable]::ToArray('`~!@#$%^&*()=+_[]{}\|;:.''",<>/?') $detectedChar = [System.Linq.Enumerable]::ToArray($ComputerName) | where {$_ -in $invalidCharactor} return $detectedChar } function CheckItemProperty ([string]$BasePath, [string]$Name) { $result = $null if (Test-Path $BasePath) { $base = Get-ItemProperty $BasePath $keyExist = ($base | Get-Member -MemberType NoteProperty).Name -contains $Name if (($null -ne $base) -and $keyExist) { Write-Verbose ("Found. Path '{0}' and Name '{1}' found. Show result." -f $BasePath, $Name) $result = [ordered]@{ path = $BasePath Property = $name value = ($base | where $Name | %{Get-ItemProperty -path $BasePath -name $Name}).$Name } } else { Write-Verbose ("Skip. Path '{0}' found but Name '{1}' not found." -f $BasePath, $Name) } } else { Write-Verbose ("Skip. Path '{0}' not found." -f $BasePath) } if ($null -eq $result) { Write-Verbose ("Skip. Item Property '{0}' not found from path '{1}'." -f $name, $BasePath) } else { return [PSCustomObject]$result } } } } # file loaded from path : \functions\Helper\ComputerName\Rename-ValentiaComputerName.ps1 #requires -Version 3.0 function Backup-ValentiaConfig { <# .Synopsis Backup CurrentConfiguration with timestamp. .DESCRIPTION Backup configuration in $Valentia.appdataconfig.root .EXAMPLE Backup-ValentiaConfig #> [OutputType([void])] [CmdletBinding()] param ( [parameter(mandatory = $false, position = 0)] [string]$configPath = "", [parameter(mandatory = $false, position = 1)] [Microsoft.PowerShell.Commands.FileSystemCmdletProviderEncoding]$encoding = $Valentia.fileEncode ) if (($configPath -eq "") -or (-not (Test-Path $configPath))) { if (Test-Path (Join-Path $valentia.originalconfig.root $valentia.originalconfig.file)) { $configPath = (Join-Path $valentia.originalconfig.root $valentia.originalconfig.file) $rootPath = $valentia.originalconfig.root $fileName = $valentia.originalconfig.file } } if (Test-Path $configPath) { $private:datePrefix = ([System.DateTime]::Now).ToString($valentia.log.dateformat) $private:backupConfigName = $datePrefix + "_" + $fileName $private:backupConfigPath = Join-Path $rootPath $backupConfigName Write-Verbose ("Backing up config file '{0}' => '{1}'." -f $configPath, $backupConfigPath) Get-Content -Path $configPath -Encoding $encoding -Raw | Out-File -FilePath $backupConfigPath -Encoding $encoding -Force } else { Write-Verbose ("Could not found configuration file '{0}'." -f $configPath) } } # file loaded from path : \functions\Helper\Config\Backup-valentiaConfig.ps1 #Requires -Version 3.0 <# .Synopsis Edit Valentia Config in Console .DESCRIPTION Read config and edit in the console .EXAMPLE Edit-ValentiaConfig #> function Edit-ValentiaConfig { [OutputType([void])] [CmdletBinding()] param ( [parameter(mandatory = $false, position = 0)] [string]$configPath = "", [parameter(mandatory = $false, position = 1)] [switch]$NoProfile ) if (($configPath -eq "") -or (-not (Test-Path $configPath))) { if (Test-Path (Join-Path $valentia.originalconfig.root $valentia.originalconfig.file)) { $configPath = (Join-Path $valentia.originalconfig.root $valentia.originalconfig.file) } } if (Test-Path $configPath) { if ($NoProfile) { PowerShell_ise.exe -File $configPath -NoProfile } else { PowerShell_ise.exe -File $configPath } } else { ("Could not found configuration file '{0}'." -f $configPath) | Write-ValentiaVerboseDebug } } # file loaded from path : \functions\Helper\Config\Edit-ValentiaConfig.ps1 #Requires -Version 3.0 <# .Synopsis Edit Valentia Config in Console .DESCRIPTION Read config and edit in the console .EXAMPLE Edit-ValentiaConfig #> function Reset-ValentiaConfig { [OutputType([void])] [CmdletBinding()] param ( [parameter(mandatory = $false, position = 0)] [string]$configPath = "", [parameter(mandatory = $false, position = 1)] [Microsoft.PowerShell.Commands.FileSystemCmdletProviderEncoding]$encoding = $Valentia.fileEncode ) if (($configPath -eq "") -or (-not (Test-Path $configPath))) { if (Test-Path (Join-Path $valentia.originalconfig.root $valentia.originalconfig.file)) { $configPath = (Join-Path $valentia.originalconfig.root $valentia.originalconfig.file) } } if (Test-Path $configPath) { . $configPath } else { ("Could not found configuration file '{0}'." -f $configPath) | Write-ValentiaVerboseDebug } } # file loaded from path : \functions\Helper\Config\Reset-ValentiaConfig.ps1 #Requires -Version 3.0 <# .Synopsis Show Valentia Config in Console .DESCRIPTION Read config and show in the console .EXAMPLE Show-ValentiaConfig #> function Show-ValentiaConfig { [OutputType([string[]])] [CmdletBinding()] param ( [parameter(mandatory = $false, position = 0)] [string]$configPath = "", [parameter(mandatory = $false, position = 1)] [Microsoft.PowerShell.Commands.FileSystemCmdletProviderEncoding]$encoding = $Valentia.fileEncode ) if (($configPath -eq "") -or (-not (Test-Path $configPath))) { if (Test-Path (Join-Path $valentia.originalconfig.root $valentia.originalconfig.file)) { $configPath = (Join-Path $valentia.originalconfig.root $valentia.originalconfig.file) } } if (Test-Path $configPath) { Get-Content -Path $configPath -Encoding $encoding } else { ("Could not found configuration file '{0}'." -f $configPath) | Write-ValentiaVerboseDebug } } # file loaded from path : \functions\Helper\Config\Show-ValentiaConfig.ps1 #Requires -Version 3.0 function Get-ValentiaCredential { [OutputType([PSCredential])] [CmdletBinding()] param ( [Parameter(mandatory = $false, position = 0)] [ValidateNotNullOrEmpty()] [string]$TargetName = $valentia.name, [Parameter(mandatory = $false, position = 1)] [ValidateNotNullOrEmpty()] [Valentia.CS.CredType]$Type = [Valentia.CS.CredType]::Generic, [Parameter(mandatory = $false, position = 2)] [ValidateNotNullOrEmpty()] [string]$AsUserName = "" ) return [Valentia.CS.CredentialManager]::Read($TargetName, $Type, $AsUserName); } # file loaded from path : \functions\Helper\Credential\Get-ValentiaCredential.ps1 #Requires -Version 3.0 function Remove-ValentiaCredential { [OutputType([void])] [CmdletBinding()] param ( [Parameter(mandatory = $false, position = 0)] [ValidateNotNullOrEmpty()] [string]$TargetName = $valentia.name, [Parameter(mandatory = $false, position = 1)] [ValidateNotNullOrEmpty()] [Valentia.CS.CredType]$Type = [Valentia.CS.CredType]::Generic ) [Valentia.CS.CredentialManager]::Remove($TargetName, $Type); } # file loaded from path : \functions\Helper\Credential\Remove-ValentiaCredential.ps1 #Requires -Version 3.0 function Set-ValentiaCredential { [OutputType([void])] [CmdletBinding()] param ( [Parameter(mandatory = $false, position = 0)] [ValidateNotNullOrEmpty()] [string]$TargetName = $valentia.name, [Parameter(mandatory = $false, position = 1)] [ValidateNotNullOrEmpty()] [System.Management.Automation.PSCredential]$Credential = (Get-Credential -User $valentia.Users.DeployUser -Message "Input password to be save."), [Parameter(mandatory = $false, position = 2)] [ValidateNotNullOrEmpty()] [Valentia.CS.CredType]$Type = [Valentia.CS.CredType]::Generic ) [Valentia.CS.CredentialManager]::Write($TargetName, $Credential, $Type) } # file loaded from path : \functions\Helper\Credential\Set-ValentiaCredential.ps1 #Requires -Version 3.0 function Test-ValentiaCredential { [OutputType([bool])] [CmdletBinding()] param ( [Parameter(mandatory = $false, position = 0)] [ValidateNotNullOrEmpty()] [string]$TargetName = $valentia.name, [Parameter(mandatory = $false, position = 1)] [ValidateNotNullOrEmpty()] [Valentia.CS.CredType]$Type = [Valentia.CS.CredType]::Generic ) [Valentia.CS.CredentialManager]::Exists($TargetName, $Type); } # file loaded from path : \functions\Helper\Credential\Test-ValentiaCredential.ps1 #Requires -Version 3.0 #-- Public Functions for CredSSP Configuration --# function Add-ValentiaCredSSPDelegateReg { [CmdletBinding()] param ( [Parameter(Position = 1, mandatory = $false)] [ValidateNotNullOrEmpty()] [string]$Keys = $valentia.credssp.AllowFreshCredentialsWhenNTLMOnly.Key ) $ErrorActionPreference = $valentia.preference.ErrorActionPreference.custom Set-StrictMode -Version latest $param = @{ Path = (Split-Path $keys -Parent) Name = (Split-Path $keys -Leaf) Value = 1 Force = $true } $result = Get-ValentiaCredSSPDelegateReg -Keys $Keys if ($result.Value -ne 1) { Set-ItemProperty @param -PassThru } elseif ($null -eq $result) { New-ItemProperty @param } } # file loaded from path : \functions\Helper\CredSSP\Private\Add-ValentiaCredSSPDelegateReg.ps1 #Requires -Version 3.0 #-- Public Functions for CredSSP Configuration --# function Add-ValentiaCredSSPDelegateRegKey { [CmdletBinding()] param ( [Parameter(Position = 0, mandatory = $false)] [ValidateNotNullOrEmpty()] [string]$Keys = $valentia.credssp.AllowFreshCredentialsWhenNTLMOnly.Key ) $ErrorActionPreference = $valentia.preference.ErrorActionPreference.custom Set-StrictMode -Version latest $param = @{ Path = (Split-Path $keys -Parent) Name = (Split-Path $keys -Leaf) Force = $true } $result = Get-ValentiaCredSSPDelegateRegKey -Keys $Keys if ($result -eq $false) { New-Item @param } } # file loaded from path : \functions\Helper\CredSSP\Private\Add-ValentiaCredSSPDelegateRegKey.ps1 #Requires -Version 3.0 #-- Public Functions for CredSSP Configuration --# function Add-ValentiaCredSSPDelegateRegKeyProperty { [CmdletBinding()] param ( [Parameter(Position = 0, mandatory = $false)] [ValidateNotNullOrEmpty()] [string]$Keys = $valentia.credssp.AllowFreshCredentialsWhenNTLMOnly.Key, [Parameter(Position = 1, mandatory = $false)] [ValidateNotNullOrEmpty()] [string]$regValue = $valentia.credssp.AllowFreshCredentialsWhenNTLMOnly.Value ) $ErrorActionPreference = $valentia.preference.ErrorActionPreference.custom Set-StrictMode -Version latest $param = @{ Path = $keys Value = $regValue Force = $true } $result = Get-ValentiaCredSSPDelegateRegKeyProperty -Keys $Keys if ($result.Value -notcontains $regValue) { $max = ($result.Key | measure -Maximum).Maximum $max++ New-ItemProperty @param -Name $max } elseif ($null -eq $result.Key) { New-ItemProperty @param -Name 1 } } # file loaded from path : \functions\Helper\CredSSP\Private\Add-ValentiaCredSSPDelegateRegKeyProperty.ps1 #Requires -Version 3.0 #-- Public Functions for CredSSP Configuration --# function Enable-ValentiaCredSSP { [CmdletBinding()] param ( [Parameter(Position = 0, mandatory = $false)] [ValidateNotNullOrEmpty()] [string]$TrustedHosts = $valentia.wsman.TrustedHosts ) $ErrorActionPreference = $valentia.preference.ErrorActionPreference.custom Set-StrictMode -Version latest try { Enable-WSManCredSSP -Role Server -Force Enable-WSManCredSSP -Role Client -DelegateComputer $TrustedHosts -Force } catch { # Unfortunately you need to repeat cpmmand again to enable Client Role. Enable-WSManCredSSP -Role Client -DelegateComputer $TrustedHosts -Force } finally { Get-WSManCredSSP } } # file loaded from path : \functions\Helper\CredSSP\Private\Enable-ValentiaCredSSP.ps1 #Requires -Version 3.0 #-- Public Functions for CredSSP Configuration --# function Get-ValentiaCredSSPDelegateReg { [CmdletBinding()] param ( [Parameter(Position = 0, mandatory = $false)] [ValidateNotNullOrEmpty()] [string]$Keys = $valentia.credssp.AllowFreshCredentialsWhenNTLMOnly.Key ) $ErrorActionPreference = $valentia.preference.ErrorActionPreference.custom Set-StrictMode -Version latest $path = (Split-Path $keys -Parent) $name = (Split-Path $keys -Leaf) Get-ItemProperty -Path $path ` | %{ $hashtable = @{ Name = $name Path = $path } if ($_ | Get-Member | where MemberType -eq NoteProperty | where Name -eq $name) { $hashtable.Add("Value", $_.$name) } else { $hashtable.Add("Value", $null) } [PSCustomObject]$hashtable } } # file loaded from path : \functions\Helper\CredSSP\Private\Get-ValentiaCredSSPDelegateReg.ps1 #Requires -Version 3.0 #-- Public Functions for CredSSP Configuration --# function Get-ValentiaCredSSPDelegateRegKey { [CmdletBinding()] param ( [Parameter(Position = 0, mandatory = $false)] [ValidateNotNullOrEmpty()] [string]$Keys = $valentia.credssp.AllowFreshCredentialsWhenNTLMOnly.Key ) $ErrorActionPreference = $valentia.preference.ErrorActionPreference.custom Set-StrictMode -Version latest $path = (Split-Path $keys -Parent) $name = (Split-Path $keys -Leaf) Get-ChildItem -Path $path ` | %{ $hashtable = @{ Name = $name PSPath = $path } if ($_ | where name -eq $name) { $true } else { $false } } } # file loaded from path : \functions\Helper\CredSSP\Private\Get-ValentiaCredSSPDelegateRegKey.ps1 #Requires -Version 3.0 #-- Public Functions for CredSSP Configuration --# function Get-ValentiaCredSSPDelegateRegKeyProperty { [CmdletBinding()] param ( [Parameter(Position = 0, mandatory = $false)] [ValidateNotNullOrEmpty()] [string]$Keys = $valentia.credssp.AllowFreshCredentialsWhenNTLMOnly.Key ) $ErrorActionPreference = $valentia.preference.ErrorActionPreference.custom Set-StrictMode -Version latest $regProperty = Get-ItemProperty -Path $keys if ($regProperty) { $regProperty ` | Get-Member -MemberType NoteProperty ` | where Name -Match "\d+" ` | %{ $name = $_.Name [PSCustomObject]@{ Key = $name Value = $regProperty.$name path = $keys } } } else { [PSCustomObject]@{ Key = "" Value = "" path = $Keys } } } # file loaded from path : \functions\Helper\CredSSP\Private\Get-ValentiaCredSSPDelegateRegKeyProperty.ps1 #Requires -Version 3.0 #-- Public Functions for CredSSP Configuration --# function Remove-ValentiaCredSSPDelegateRegKey { [CmdletBinding()] param ( [Parameter(Position = 0, mandatory = $false)] [ValidateNotNullOrEmpty()] [string]$TrustedHosts = $valentia.wsman.TrustedHosts, [Parameter(Position = 1, mandatory = $false)] [ValidateNotNullOrEmpty()] [string]$Keys = $valentia.credssp.AllowFreshCredentialsWhenNTLMOnly.Key, [Parameter(Position = 2, mandatory = $false)] [ValidateNotNullOrEmpty()] [string]$regValue = $valentia.credssp.AllowFreshCredentialsWhenNTLMOnly.Value ) $ErrorActionPreference = $valentia.preference.ErrorActionPreference.custom Set-StrictMode -Version latest $result = Get-ValentiaCredSSPDelegateRegKey -TrustedHosts $TrustedHosts -Keys $Keys if ($result.Value -contains $regValue) { $result | %{Remove-ItemProperty -Path $_.pspath -Name $_.Key -Force} } } # file loaded from path : \functions\Helper\CredSSP\Private\Remove-ValentiaCredSSPDelegateRegKey.ps1 #Requires -Version 3.0 #-- helper for DNS Entry --# <# .Synopsis Get HostName to IPAddress Entry / IPAddress to HostName Entry .DESCRIPTION using Dns.GetHostEntryAsync Method. You can skip Exception for none exist HostNameOrAddress result by adding -SkipException $true .EXAMPLE Get-HostEntryAsync -HostNameOrAddress "google.com", "173.194.38.100", "neue.cc" # Test Success .EXAMPLE "google.com", "173.194.38.100", "neue.cc" | Get-HostEntryAsync # Pipeline Input .EXAMPLE Get-HostEntryAsync -HostNameOrAddress "google.com", "173.194.38.100", "hogemopge.fugapiyo" # Error will stop execution .EXAMPLE Get-HostEntryAsync -HostNameOrAddress "google.com", "173.194.38.100", "hogemopge.fugapiyo" -SkipException $true # Skip Error result .LINK http://msdn.microsoft.com/en-US/library/system.net.dns.gethostentryasync(v=vs.110).aspx #> function Get-ValentiaHostEntryAsync { [CmdletBinding()] param ( [parameter(mandatory = $true, Position = 0, ValueFromPipeline = 1, ValueFromPipelineByPropertyName = 1)] [string[]]$HostNameOrAddress, [parameter(mandatory = $false, Position = 1, ValueFromPipelineByPropertyName = 1)] [bool]$SkipException = $false ) process { foreach ($name in $HostNameOrAddress) { $x = [System.Net.DNS]::GetHostEntryAsync($name) $x.ConfigureAwait($false) > $null $task = [PSCustomObject]@{ HostNameOrAddress = $name Task = $x } $tasks.Add($task) } } end { try { [System.Threading.Tasks.Task]::WaitAll($tasks.Task) } catch { $stackStrace = $_ $throw = $Tasks ` | where {$_.Task.Exception} ` | %{ $stackStrace [System.Environment]::NewLine "Error HostNameOrAddress : {0}" -f $_.HostNameOrAddress [System.Environment]::NewLine $_.Task.Exception } if (-not $SkipException) { throw $throw } else { Write-Verbose ("-SkipException was {0}. Skipping Error : '{1}'." -f $SkipException, "$(($Tasks | where {$_.Task.Exception}).HostNameOrAddress -join ', ')") } } finally { foreach ($task in $tasks.Task) { [System.Net.IPHostEntry]$IPHostEntry = $task.Result $IPHostEntry } } } begin { $tasks = New-Object 'System.Collections.Generic.List[PSCustomObject]' } } # file loaded from path : \functions\Helper\DNS\Get-ValentiaHostEntryAsync.ps1 #Requires -Version 3.0 #-- function helper for Dynamic Param --# <# .SYNOPSIS This cmdlet will return Dynamic param dictionary .DESCRIPTION You can use this cmdlet to define Dynamic Param .NOTES Author: guitrrapc Created: 02/03/2014 .EXAMPLE function Show-ValentiaDynamicParamMulti { [CmdletBinding()] param( [parameter(position = 6)] $nyao ) dynamicParam { $dynamicParams = ( @{Mandatory = $true name = "hoge" Options = "hoge","piyo" position = 0 Type = "System.String[]" validateSet = $true valueFromPipelineByPropertyName = $true}, @{Mandatory = $true name = "foo" Options = 1,2,3,4,5 position = 1 Type = "System.Int32[]" validateSet = $true}, @{DefaultValue = (4,2,5) Mandatory = $false name = "bar" Options = 1,2,3,4,5 position = 2 Type = "System.Int32[]" validateSet = $false} ) $dynamic = New-ValentiaDynamicParamMulti -dynamicParams $dynamicParams return $dynamic } begin { } process { $PSBoundParameters.hoge $PSBoundParameters.foo if ($PSBoundParameters.ContainsKey('bar')) { $PSBoundParameters.bar $PSBoundParameters.bar.GetType().FullName } else { $bar = $dynamic.bar.Value $bar $bar.GetType().FullName } } } "Test 1 ---------------------" Show-ValentiaDynamicParamMulti -hoge hoge -foo 1,2,3,4 "Test 2 ---------------------" Show-ValentiaDynamicParamMulti -hoge piyo -foo 2 -bar 2 #> function New-ValentiaDynamicParamMulti { [CmdletBinding()] param ( [parameter(mandatory = $true, position = 0, valueFromPipeline = 1, valueFromPipelineByPropertyName = 1)] [hashtable[]]$dynamicParams ) begin { $dynamicParamLists = New-ValentiaDynamicParamList -dynamicParams $dynamicParams $dictionary = New-Object System.Management.Automation.RuntimeDefinedParameterDictionary } process { foreach ($dynamicParamList in $dynamicParamLists) { # create attributes $attributes = New-Object System.Management.Automation.ParameterAttribute $attributes.ParameterSetName = "__AllParameterSets" ( "helpMessage", "mandatory", "parameterSetName", "position", "valueFromPipeline", "valueFromPipelineByPropertyName", "valueFromRemainingArguments" ) ` | %{ if($dynamicParamList.$_) { $attributes.$_ = $dynamicParamList.$_ } } # create attributes Collection $attributesCollection = New-Object 'Collections.ObjectModel.Collection[System.Attribute]' $attributesCollection.Add($attributes) # create validation set if ($dynamicParamList.validateSet) { $validateSetAttributes = New-Object System.Management.Automation.ValidateSetAttribute $dynamicParamList.options $attributesCollection.Add($validateSetAttributes) } # Set default type or get from dynamicparam # Priority # 1. Type KV # 2. Type of DefaultValue # 3. System.Object[] if ($dynamicParamList.type) { $type = [Type]::GetType($dynamicParamList.Type) } else { if ($dynamicParamList.defaultValue) { $DefaultValueType = $dynamicParamList.defaultValue.GetType().FullName $type = [Type]::GetType($DefaultValueType) } else { $type = [Type]::GetType("System.Object[]") } } if ($null -eq $type) { throw "type not defined or Null exception! Make sure you have set fullname for the type : '{0}'" -f $dynamicParamList.type } # create RuntimeDefinedParameter $runtimeDefinedParameter = New-Object -TypeName System.Management.Automation.RuntimeDefinedParameter @($dynamicParamList.name, $type, $attributesCollection) # Set Default Value if passed if ($dynamicParamList.defaultValue) { if ($dynamicParamList.defaultValue -is $type) { $runtimeDefinedParameter.Value = $dynamicParamList.defaultValue } elseif ($dynamicParamList.defaultValue -as $type) { Write-Verbose ("Convert Type for ParameterName '{0}'. DefaultValue '{1}' convert from '{2}' to '{3}'" ` -f $dynamicParamList.name, $dynamicParamLists.defaultValue, $dynamicParamList.defaultValue.GetType().FullName, $type) $runtimeDefinedParameter.Value = $dynamicParamList.defaultValue -as $type } else { throw "Cannot convert Type for ParameterName '{0}'. DefaultValue '{1}' could not convert from '{2}' to '{3}'" ` -f $dynamicParamList.name, $dynamicParamLists.defaultValue, $dynamicParamList.defaultValue.GetType().FullName, $type } } # create Dictionary $dictionary.Add($dynamicParamList.name, $runtimeDefinedParameter) } } end { # return result return $dictionary } } <# .SYNOPSIS This cmdlet will return Dynamic param list item for dictionary .DESCRIPTION You can pass this list to DynamicPramMulti to create Dynamic Param #> function New-ValentiaDynamicParamList { [CmdletBinding()] param ( [parameter( mandatory = $true, position = 0, valueFromPipeline = 1, valueFromPipelineByPropertyName = 1)] [hashtable[]] $dynamicParams ) begin { # create generic list $list = New-Object System.Collections.Generic.List[HashTable] # create key check array [string[]]$keyCheckInputItems = "helpMessage", "mandatory", "name", "parameterSetName", "options", "position", "valueFromPipeline", "valueFromPipelineByPropertyName", "valueFromRemainingArguments", "validateSet", "Type", "DefaultValue" $keyCheckList = New-Object System.Collections.Generic.List[String] $keyCheckList.AddRange($keyCheckInputItems) # sort dynamicParams hashtable by position $newDynamicParams = Sort-ValentiaDynamicParamHashTable -dynamicParams $dynamicParams } process { foreach ($dynamicParam in $newDynamicParams) { $invalidParamter = $dynamicParam.Keys | where {$_ -notin $keyCheckList} if ($($invalidParamter).count -ne 0) { throw ("Invalid parameter '{0}' found. Please use parameter from '{1}'" -f $invalidParamter, ("$keyCheckInputItems" -replace " "," ,")) } else { if (-not $dynamicParam.Keys.contains("name")) { throw ("You must specify mandatory parameter '{0}' to hashtable key." -f "name") } elseif (-not $dynamicParam.Keys.contains("options")) { throw ("You must specify mandatory parameter '{0}' to hashtable key." -f "options") } else { $list.Add($dynamicParam) } } } } end { return $list } } function Sort-ValentiaDynamicParamHashTable { [CmdletBinding()] param ( [parameter( mandatory = $true, position = 0, valueFromPipeline = 1, valueFromPipelineByPropertyName = 1)] [hashtable[]] $dynamicParams ) begin { # get max number of position for null position item $max = ($dynamicParams.position | measure -Maximum).Maximum } process { # output PSCustomObject[Name<SortedPosition>,Value<DynamicParamHashTable>]. posision is now sorted. $h = $dynamicParams ` | %{ $history = New-Object System.Collections.Generic.List[int] $hash = @{} # temp posision for null item. This set as (max + number of collection items) $num = $max + $parameters.Length }{ Write-Verbose ("position is '{0}'." -f $position) $position = $_.position #region null check if ($null -eq $position) { Write-Verbose ("position is '{0}'. set current max index '{1}'" -f $position, $num) $position = $num $num++ } #endregion #region dupricate check if ($position -notin $history) { Write-Verbose ("position '{0}' not found in '{1}'. Add to history." -f $position, ($history -join ", ")) $history.Add($position) } else { $changed = $false while ($position -in $history) { Write-Verbose ("position '{0}' found in '{1}'. Start increment." -f $position, ($history -join ", ")) $position++ $changed = $true } Write-Verbose (" incremented position '{0}' not found in '{1}'. Add to history." -f $position, ($history -join ", ")) if ($changed){$history.Add($position)} } #endregion #region set temp hash Write-Verbose ("Set position '{0}' as name of temp hash." -f $position) $hash."$position" = $_ #endregion }{[PSCustomObject]$hash} } end { # get index for each object $index = [int[]](($h | Get-Member -MemberType NoteProperty).Name) | sort # return sorted hash order by index return $index | %{$h.$_} } } # file loaded from path : \functions\Helper\DynamicParam\New-ValentiaDynamicParamMulti.ps1 #Requires -Version 3.0 #-- Helper Functions --# <# .SYNOPSIS Get encoding from the file your tried to read. .DESCRIPTION You can specify what is the encoding used in the file you want to check. Will return encoding name used in PowerShell, it means you can pass returned value to Get-Content or other. .NOTES Author: guitarrapc Created: 19/Nov/2013 .EXAMPLE Get-ValentiaFileEncoding -Path hogehoge.ps1 -------------------------------------------- Get encoding of hogehoge.ps1 #> function Get-ValentiaFileEncoding { [CmdletBinding()] param ( [parameter(mandatory = $true, position = 0)] [string]$path ) if (Test-Path $path) { $bytes = [byte[]](Get-Content $Path -Encoding byte -ReadCount 4 -TotalCount 4) if(-not $bytes) { return 'utf8' } switch -regex ('{0:x2}{1:x2}{2:x2}{3:x2}' -f $bytes[0],$bytes[1],$bytes[2],$bytes[3]) { '^efbbbf' {return 'utf8'} '^2b2f76' {return 'utf7'} '^fffe' {return 'unicode'} '^feff' {return 'bigendianunicode'} '^0000feff' {return 'utf32'} default {return 'ascii'} } } else { throw ("path '{0}' not exist excemption." -f $path) } } # file loaded from path : \functions\Helper\Encoding\Get-ValentiaFileEncoding.ps1 #Requires -Version 3.0 #-- Prerequisite OS Setting Module Functions --# <# .SYNOPSIS Create New Firewall Rule for PowerShell Remoting .DESCRIPTION Will allow PowerShell Remoting port for firewall .NOTES Author: guitarrapc Created: 18/Jul/2013 .EXAMPLE Enable-PSRemotingFirewallRule -------------------------------------------- Add PowerShellRemoting-In accessible rule to Firewall. #> function New-ValentiaPSRemotingFirewallRule { [CmdletBinding()] param ( [Parameter(Position = 0, mandatory = $false, HelpMessage = "Input PowerShellRemoting-In port. default is 5985")] [int]$PSRemotePort = 5985, [Parameter(Position = 1, mandatory = $false, HelpMessage = "Input Name of Firewall rule for PowerShellRemoting-In.")] [string]$Name = "Windows Remote Management (HTTP-In)", [Parameter(Position = 2, mandatory = $false, HelpMessage = "Input Decription of Firewall rule for PowerShellRemoting-In.")] [string]$Description = "Windows PowerShell Remoting required to open for public connection. not for private network.", [Parameter(Position = 2, mandatory = $false, HelpMessage = "Input Group of Firewall rule for PowerShellRemoting-In.")] [string]$Group = "Windows Remote Management" ) $ErrorActionPreference = $valentia.preference.ErrorActionPreference.custom Set-StrictMode -Version latest if (-not((Get-NetFirewallRule | where Name -eq $Name) -and (Get-NetFirewallPortFilter -Protocol TCP | where Localport -eq $PSRemotePort))) { Write-Verbose ("Windows PowerShell Remoting port TCP $PSRemotePort was not opend. Set new rule '{1}'" -f $PSRemotePort, $Name) New-NetFirewallRule ` -Name $Name ` -DisplayName $Name ` -Description $Description ` -Group $Group ` -Enabled True ` -Profile Any ` -Direction Inbound ` -Action Allow ` -EdgeTraversalPolicy Block ` -LooseSourceMapping $False ` -LocalOnlyMapping $False ` -OverrideBlockRules $False ` -Program Any ` -LocalAddress Any ` -RemoteAddress Any ` -Protocol TCP ` -LocalPort $PSRemotePort ` -RemotePort Any ` -LocalUser Any ` -RemoteUser Any } else { "Windows PowerShell Remoting port TCP 5985 was alredy opened. Get Firewall Rule." | Write-ValentiaVerboseDebug Get-NetFirewallPortFilter -Protocol TCP | where Localport -eq 5985 } if ((Get-WinSystemLocale).Name -eq "ja-JP") { $japanesePSRemoteingEnableRule = "Windows リモート管理 (HTTP 受信)" if (-not((Get-NetFirewallRule | where DisplayName -eq $japanesePSRemoteingEnableRule | where Profile -eq "Any") -and (Get-NetFirewallPortFilter -Protocol TCP | where Localport -eq $PSRemotePort))) { ("日本語OSと検知しました。'{0}' という名称で TCP '{1}' をファイアウォールに許可します。" -f $japanesePSRemoteingEnableRule, 5985) | Write-ValentiaVerboseDebug New-NetFirewallRule ` -Name $japanesePSRemoteingEnableRule ` -DisplayName $japanesePSRemoteingEnableRule ` -Description $Description ` -Group $Group ` -Enabled True ` -Profile Any ` -Direction Inbound ` -Action Allow ` -EdgeTraversalPolicy Block ` -LooseSourceMapping $False ` -LocalOnlyMapping $False ` -OverrideBlockRules $False ` -Program Any ` -LocalAddress Any ` -RemoteAddress Any ` -Protocol TCP ` -LocalPort $PSRemotePort ` -RemotePort Any ` -LocalUser Any ` -RemoteUser Any } } } # file loaded from path : \functions\Helper\FireWall\Firewall\New-ValentiaPSRemotingFirewallRule.ps1 #Requires -Version 3.0 #-- Prerequisite Deploy Setting Module Functions --# <# .SYNOPSIS Configure Deployment Path .DESCRIPTION This cmdlet will create valentis deploy folders for each Branch path. .NOTES Author: guitarrapc Created: 18/Jul/2013 .EXAMPLE New-valentiaFolder -------------------------------------------- create as default #> function New-ValentiaFolder { [CmdletBinding()] param ( [Parameter(Position = 0, mandatory = $false, HelpMessage = "Root Folder path.")] [ValidateNotNullOrEmpty()] [string]$RootPath = $valentia.RootPath, [Parameter(Position = 1, mandatory = $false, HelpMessage = "Branch Path path.")] [ValidateNotNullOrEmpty()] [ValentiaBranchPath[]]$BranchPath = [Enum]::GetNames([ValentiaBranchPath]), [Parameter(Position = 2, mandatory = $false, HelpMessage = "Log Folder path.")] [ValidateNotNullOrEmpty()]$LogFolder = $valentia.Log.path, [Parameter(Position = 3, mandatory = $false, HelpMessage = "Suppress output directory create info.")] [switch]$Quiet ) begin { $ErrorActionPreference = $valentia.preference.ErrorActionPreference.custom Set-StrictMode -Version latest # Create Fullpath String if (($BranchPath).count -ne 0) { $DeployFolders = $BranchPath | %{Join-Path $RootPath $_} } $directories = New-Object System.Collections.Generic.List[System.IO.DirectoryInfo] } process { # Check each Fupllpath and create if not exist. foreach ($Deployfolder in $DeployFolders) { if(-not (Test-Path $DeployFolder)) { ("'{0}' not exist, creating." -f $DeployFolder) | Write-ValentiaVerboseDebug $output = New-Item -Path $DeployFolder -ItemType directory -Force $directories.Add($output) } else { ("'{0}' already exist, skip." -f $DeployFolder) | Write-ValentiaVerboseDebug $output = Get-Item -Path $DeployFolder $directories.Add($output) } } # Check Log Folder and create if not exist if(-not (Test-Path $LogFolder)) { ("'{0}' not exist, creating." -f $LogFolder) | Write-ValentiaVerboseDebug $output = New-Item -Path $LogFolder -ItemType directory -Force $directories.Add($output) } else { ("'{0}' already exist, skip." -f $LogFolder) | Write-ValentiaVerboseDebug $output = Get-Item -Path $LogFolder $directories.Add($output) } } end { if (-not $Quiet) { ($directories).FullName } # Cleanup valentia Environment Invoke-ValentiaClean } } # file loaded from path : \functions\Helper\Folder\New-ValentiaFolder.ps1 #Requires -Version 3.0 #-- Deploy Folder/File Module Functions --# # target <# .SYNOPSIS Get ipaddress or NetBIOS from DeployGroup File specified .DESCRIPTION This cmdlet will read Deploy Group path and set them into array of Deploygroups. .NOTES Author: guitarrapc Created: 18/Jul/2013 .EXAMPLE target production-hoge.ps1 -------------------------------------------- read production-hoge.ps1 from deploy group branch path. .EXAMPLE target production-hoge.ps1 c:\test -------------------------------------------- read production-hoge.ps1 from c:\test. #> function Get-ValentiaGroup { [CmdletBinding()] param ( [Parameter(Position = 0, mandatory = $true, ValueFromPipeline = 1, ValueFromPipelineByPropertyName = 1, HelpMessage = "Input target of deploy clients as [DeployGroup filename you sat at deploygroup Folder] or [ipaddress].")] [string[]]$DeployGroups, [Parameter(Position = 1, mandatory = $false, HelpMessage = "Input DeployGroup Folder path if changed from default.")] [ValidateNotNullOrEmpty()] [string]$DeployFolder = (Join-Path $Script:valentia.RootPath ([ValentiaBranchPath]::Deploygroup)) ) process { foreach ($DeployGroup in $DeployGroups) { # Get valentia.deployextension information ('Set DeployGroupFile Extension as "$valentia.deployextension" : {0}' -f $valentia.deployextension) | Write-ValentiaVerboseDebug $DeployExtension = $valentia.deployextension 'Read DeployGroup and return $DeployMemebers' | Write-ValentiaVerboseDebug Read-ValentiaGroup -DeployGroup $DeployGroup } } begin { # Get valentiaGroup function Read-ValentiaGroup { [CmdletBinding()] param ( [Parameter(Position = 0, Mandatory)] [string] $DeployGroup ) if ($DeployGroup.EndsWith($DeployExtension)) # if DeployGroup last letter = Extension is same as $DeployExtension { $DeployGroupPath = Join-Path $DeployFolder $DeployGroup -Resolve ("Read DeployGroupPath {0} where letter not contain # inline." -f $DeployGroupPath) | Write-ValentiaVerboseDebug return (Select-String -path $DeployGroupPath -Pattern ".*#.*" -notmatch -Encoding $valentia.fileEncode | Select-String -Pattern "\w" -Encoding $valentia.fileEncode).line } else { return $DeployGroup } } } } # file loaded from path : \functions\Helper\Group\Get-ValentiaGroup.ps1 #Requires -Version 3.0 #-- Deploy Folder/File Module Functions --# # ipremark <# .SYNOPSIS Remark Deploy ip from deploygroup file .DESCRIPTION This cmdlet remark deploygroup ipaddresses from $valentia.root\$valentia.branch.deploygroup not to refer the ipaddress .NOTES Author: guitarrapc Created: 04/Oct/2013 .EXAMPLE Invoke-valentiaDeployGroupRemark -remarkIPAddresses 10.0.0.10,10.0.0.11 -overWrite -Verbose -------------------------------------------- replace 10.0.0.10 and 10.0.0.11 with #10.0.0.10 and #10.0.0.11 then replace file. (like sed -f "s/^10.0.0.10$/#10.0.0.10" -i) Invoke-valentiaDeployGroupRemark -remarkIPAddresses 10.0.0.10,10.0.0.11 -Verbose -------------------------------------------- replace 10.0.0.10 and 10.0.0.11 with #10.0.0.10 and #10.0.0.11 (like sed -f "s/^10.0.0.10$/#10.0.0.10") Invoke-valentiaDeployGroupRemark -remarkIPAddresses 10.0.0.10,10.0.0.11 -Verbose -Recurse $false -Path d:\hoge -------------------------------------------- Check d:\hoge folder without recursive. This means it only check path you desired. #> function Invoke-ValentiaDeployGroupRemark { [CmdletBinding()] param ( [parameter(position = 0, mandatory = $true, ValueFromPipeline = 1, ValueFromPipelineByPropertyName = 1)] [Alias("IPAddress", "HostName")] [string[]]$remarkIPAddresses, [parameter(position = 1, mandatory = $false,ValueFromPipelineByPropertyName = 1)] [string]$Path = (Join-Path $valentia.RootPath ([ValentiaBranchPath]::Deploygroup)), [parameter(position = 2, mandatory = $false, ValueFromPipelineByPropertyName = 1)] [bool]$Recurse = $true, [parameter(position = 3, mandatory = $false, ValueFromPipelineByPropertyName = 1)] [switch]$overWrite, [parameter(position = 4, mandatory = $false, ValueFromPipelineByPropertyName = 1)] [Microsoft.PowerShell.Commands.FileSystemCmdletProviderEncoding]$encoding = $valentia.fileEncode ) begin { if (-not (Test-Path $Path)){ throw New-Object System.IO.FileNotFoundException ("Path $Path not found Exception!!", "$Path")} } end { Get-ChildItem -Path $Path -Recurse:$Recurse -File ` | %{ foreach ($remarkIPAddress in $remarkIPAddresses) { if ($overWrite) { Invoke-ValentiaSed -path $_.FullName -searchPattern "^$remarkIPAddress$" -replaceWith "#$remarkIPAddress" -encoding $encoding -overWrite } else { Invoke-ValentiaSed -path $_.FullName -searchPattern "^$remarkIPAddress$" -replaceWith "#$remarkIPAddress" -encoding $encoding } } } } } # file loaded from path : \functions\Helper\Group\Invoke-ValentiaDeployGroupRemark.ps1 #Requires -Version 3.0 #-- Deploy Folder/File Module Functions --# # ipunremark <# .SYNOPSIS Unremark Deploy ip from deploygroup file .DESCRIPTION This cmdlet unremark deploygroup ipaddresses from $valentia.root\$valentia.branch.deploygroup to refer the ipaddress. .NOTES Author: guitarrapc Created: 04/Oct/2013 .EXAMPLE Invoke-valentiaDeployGroupUnremark -unremarkIPAddresses 10.0.0.10,10.0.0.11 -overWrite -Verbose -------------------------------------------- replace #10.0.0.10 and #10.0.0.11 with 10.0.0.10 and 10.0.0.11 then replace file (like sed -f "s/^#10.0.0.10$/10.0.0.10" -i) Invoke-valentiaDeployGroupUnremark -unremarkIPAddresses 10.0.0.10,10.0.0.11 -Verbose -------------------------------------------- replace #10.0.0.10 and #10.0.0.11 with 10.0.0.10 and 10.0.0.11 (like sed -f "s/^#10.0.0.10$/10.0.0.10") Invoke-valentiaDeployGroupUnremark -remarkIPAddresses 10.0.0.10,10.0.0.11 -Verbose -Recurse $false -Path d:\hoge -------------------------------------------- Check d:\hoge folder without recursive. This means it only check path you desired. #> function Invoke-ValentiaDeployGroupUnremark { [CmdletBinding()] param ( [parameter(position = 0, mandatory = $true, ValueFromPipeline = 1, ValueFromPipelineByPropertyName = 1)] [Alias("IPAddress", "HostName")] [string[]]$unremarkIPAddresses, [parameter(position = 1, mandatory = $false, ValueFromPipelineByPropertyName = 1)] [string]$Path = (Join-Path $valentia.RootPath ([ValentiaBranchPath]::Deploygroup)), [parameter(position = 2, mandatory = $false, ValueFromPipelineByPropertyName = 1)] [bool]$Recurse = $true, [parameter(position = 3, mandatory = $false)] [switch]$overWrite, [parameter(position = 4, mandatory = $false)] [Microsoft.PowerShell.Commands.FileSystemCmdletProviderEncoding] $encoding = $valentia.fileEncode ) begin { if (-not (Test-Path $Path)){ throw New-Object System.IO.FileNotFoundException ("Path $Path not found Exception!!", "$Path")} } end { Get-ChildItem -Path $Path -Recurse:$Recurse -File ` | %{ foreach ($unremarkIPAddress in $unremarkIPAddresses) { if ($overWrite) { Invoke-ValentiaSed -path $_.FullName -searchPattern "^#$unremarkIPAddress$" -replaceWith "$unremarkIPAddress" -encoding $encoding -overWrite } else { Invoke-ValentiaSed -path $_.FullName -searchPattern "^#$unremarkIPAddress$" -replaceWith "$unremarkIPAddress" -encoding $encoding } } } } } # file loaded from path : \functions\Helper\Group\Invoke-ValentiaDeployGroupUnremark.ps1 #Requires -Version 3.0 #-- Deploy Folder/File Module Functions --# <# .SYNOPSIS Create new DeployGroup File written "target PC IP/hostname" for PS-RemoteSession .DESCRIPTION This cmdlet will create valentis deploy group file to specify deploy targets. .NOTES Author: guitarrapc Created: 18/Jul/2013 .EXAMPLE New-valentiaGroup -DeployClients "10.0.4.100","10.0.4.101" -FileName new.ps1 -------------------------------------------- write 10.0.4.100 and 10.0.4.101 to create deploy group file as "new.ps1". #> function New-ValentiaGroup { [CmdletBinding()] param ( [Parameter(Position = 0, mandatory = $true, ValueFromPipeline = 1, ValueFromPipelineByPropertyName = 1, HelpMessage = "Specify IpAddress or NetBIOS name for deploy target clients.")] [string[]]$DeployClients, [Parameter(Position = 1, mandatory = $true, HelpMessage = "Input filename to output DeployClients")] [string]$FileName, [Parameter(Position = 2, mandatory = $false, HelpMessage = "Specify folder path to deploy group. defailt is Deploygroup branchpath")] [string]$DeployGroupsFolder = (Join-Path $Script:valentia.RootPath ([ValentiaBranchPath]::Deploygroup)), [Parameter(Position = 3, mandatory = $false, HelpMessage = "If you want to add item to exist file.")] [switch]$Add, [Parameter(Position = 4, mandatory = $false, HelpMessage = "If you want to popup confirm message when file created.")] [switch]$Confirm, [Parameter(Position = 5, mandatory = $false, HelpMessage = "If you want to Show file information when operation executed.")] [switch]$PassThru ) process { if($PSBoundParameters.ContainsKey('Add')) { $DeployClients | Add-Content @param } else { $DeployClients | Set-Content @param } } begin { $ErrorActionPreference = $valentia.preference.ErrorActionPreference.custom Set-StrictMode -Version latest # check FileName is null or empty try { if ([string]::IsNullOrEmpty($FileName)) { throw '"$FileName" was Null or Enpty, input DeployGroup FileName.' } else { $DeployPath = Join-Path $DeployGroupsFolder $FileName } } catch { throw $_ } # set splatting $param = @{ path = $DeployPath Encoding = $valentia.fileEncode Force = $true Confirm = $PSBoundParameters.ContainsKey('Confirm') PassThru = $PSBoundParameters.ContainsKey('PassThru') } } end { if (Test-Path $DeployPath) { Get-ChildItem -Path $DeployPath } else { Write-Error ("{0} not existing." -f $DeployPath) } # Cleanup valentia Environment Invoke-ValentiaClean } } # file loaded from path : \functions\Helper\Group\New-ValentiaGroup.ps1 #Requires -Version 3.0 #-- Deploy Folder/File Module Functions --# <# .SYNOPSIS Show valentia deploygroup file (.ps1) list .DESCRIPTION This cmdlet will show files (extension = $valentia.deployextension = default is '.ps1') in [ValentiaBranchPath]::Deploygroup folder. .NOTES Author: guitarrapc Created: 29/Oct/2013 .EXAMPLE Show-ValentiaGroup -------------------------------------------- show files in $valentia.Root\([ValentiaBranchPath]::Deploygroup) folder. #> function Show-ValentiaGroup { [CmdletBinding()] param ( [Parameter(Position = 0, mandatory = $false, HelpMessage = "Input branch folder to show.")] [ValentiaBranchPath[]]$Branches = ([ValentiaBranchPath]::Deploygroup), [Parameter(Position = 1, mandatory = $false, HelpMessage = "Use if you want to search directory recursibly.")] [switch]$recurse ) $DeployExtension = $valentia.deployextension foreach ($branch in $Branches) { if ($branch.Length -eq 0) { throw '"$Branch" was Null or Empty, input BranchName.' } else { ("Creating full path and resolving with '{0}' and '{1}'" -f $valentia.RootPath, ([ValentiaBranchPath]::$branch)) | Write-ValentiaVerboseDebug $BranchFolder = Join-Path $valentia.RootPath $branch -Resolve # show items $param = @{ Path = $BranchFolder Recurse = if($PSBoundParameters.recurse.IsPresent){$true}else{$false} } Get-ChildItem @param | where extension -eq $DeployExtension } } } # file loaded from path : \functions\Helper\Group\Show-ValentiaGroup.ps1 #Requires -Version 3.0 #-- helper for write verbose and debug --# <# .SYNOPSIS Pass to write-verbose / debug for input. .DESCRIPTION You can show same message for verbose and debug. .NOTES Author: guitarrapc Created: 16/Feb/2014 .EXAMPLE "hoge" | Write-ValentiaVerboseDebug -------------------------------------------- Will show both Verbose message and Debug. #> filter Write-ValentiaVerboseDebug { Write-Verbose -Message $_ Write-Debug -Message $_ } # file loaded from path : \functions\Helper\HostOutput\Write-ValentiaVerboseDebug.ps1 #Requires -Version 3.0 #-- Prerequisite OS Setting Module Functions --# <# .SYNOPSIS Disable EnhancedIESecutiry for Internet Explorer .DESCRIPTION Change registry to disable EnhancedIESecutiry. It will only work for [Windows Server] not for Workstation, and [Windows Server 2008 R2] and higer. .NOTES Author: guitarrapc Created: 18/Jul/2013 .EXAMPLE Disable-ValentiaEnhancedIESecutiry -------------------------------------------- Disable IEEnhanced security. #> function Disable-ValentiaEnhancedIESecutiry { [CmdletBinding()] param ( [Parameter(Position = 0, mandatory = $false, HelpMessage = "Registry key for Admin.")] [string]$AdminKey = "HKLM:\SOFTWARE\Microsoft\Active Setup\Installed Components\{A509B1A7-37EF-4b3f-8CFC-4F3A74704073}", [Parameter(Position = 0, mandatory = $false, HelpMessage = "Registry key for User.")] [string]$UserKey = "HKLM:\SOFTWARE\Microsoft\Active Setup\Installed Components\{A509B1A8-37EF-4b3f-8CFC-4F3A74704073}" ) $ErrorActionPreference = $valentia.preference.ErrorActionPreference.custom Set-StrictMode -Version latest # get os version, Windows 7 will be "6 1 0 0" $osversion = [Environment]::OSVersion.Version # Higher than $valentia.supportWindows $minimumversion = New-Object 'Version' $valentia.supportWindows # check osversion higher than valentia support version if ($osversion -ge $minimumversion) { if (Test-Path $AdminKey) { if ((Get-ItemProperty -Path $AdminKey -Name "IsInstalled").IsInstalled -eq "1") { Set-ItemProperty -Path $AdminKey -Name "IsInstalled" -Value 0 $IsstatusChanged = $true } else { $IsstatusChanged = $false } } else { $IsstatusChanged = $false } if (Test-Path $UserKey) { if ((Get-ItemProperty -Path $UserKey -Name "IsInstalled").IsInstalled -eq "1") { Set-ItemProperty -Path $UserKey -Name "IsInstalled" -Value 0 $IsstatusChanged = $true } else { $IsstatusChanged = $false } } else { $IsstatusChanged = $false } if ($IsstatusChanged) { # Stop Internet Exploer if launch "IE Enhanced Security Configuration (ESC) has been disabled. Checking IE to stop process." | Write-ValentiaVerboseDebug Get-Process | where Name -eq "iexplore" | Stop-Process -Confirm } else { "IE Enhanced Security Configuration (ESC) had already been disabled. Nothing will do." | Write-ValentiaVerboseDebug } } else { Write-Warning -Message ("Your Operating System '{0}', Version:'{1}' was lower than valentia supported version '{2}'." -f ` (Get-CimInstance -class Win32_OperatingSystem).Caption, $osversion, $minimumversion) } } # file loaded from path : \functions\Helper\IE\Private\Disable-ValentiaEnhancedIESecutiry.ps1 #Requires -Version 3.0 #-- Running prerequisite Initialize OS Setting Module Functions --# # Initial <# .SYNOPSIS Initializing valentia PSRemoting environment for Deploy Server and client. .DESCRIPTION Make sure to Run as Admin Priviledge. This function will execute followings. 1. Set-ExecutionPolicy (Default : RemoteSigned) 2. Add PowerShell Remoting Inbound rule to Firewall 3. Network Connection Profile Setup 4. Disable PSRemoting and CredSSP for reset 5. Enable-PSRemoting 6. Add hosts to trustedHosts 7. Set WSMan MaxShellsPerUser from 25 to 100 8. Set WSMan MaxMBPerUser unlimited. 9. Set WSMan MaxProccessesPerShell unlimited. 10. Enable CredSSP for trustedHosts. 11. Restart Service WinRM 12. Disable Enhanced Security for Internet Explorer 13. Create OS user for Deploy connection. 14. Server Only : Create Deploy Folders 15. Server Only : Create/Revise Deploy user credential secure file. 16. Set HostName for the windows. 17. Get Status for Reboot Status and decide. .PARAMETER Server Select this switch to Initialize setup for Deploy Server. (Ristricted with Client) .PARAMETER Client Select this switch to Initialize setup for Deploy Client. (Ristricted with Server) .PARAMETER NoOSUser Select this switch If you don't want to initialize Deploy User. (Ristricted with Server) .PARAMETER NoPassSave Select this switch If you don't want to Save/Revise password. (Ristricted with Server) .PARAMETER HostUsage set usage for the host. (Ristricted with Server) .PARAMETER NoReboot Select this switch If you don't want to Reboot. .PARAMETER Force Select this switch If you want to Forece Restart without prompt. .PARAMETER TrustedHosts Input Trusted Hosts you want to enable. Default : "*" .PARAMETER SkipEnablePSRemoting Select this switch If you want to skip setup PSRemoting. .NOTES Author: guitarrapc Created: 18/Jul/2013 .EXAMPLE Initialize-valentiaEnvironment -Server -------------------------------------------- Setup Server Environment .EXAMPLE Setup Client Environment -------------------------------------------- Initialize-valentiaEnvironment -Client .EXAMPLE Initialize-valentiaEnvironment -Client -NoOSUser -------------------------------------------- Setup Client Environment and Skip Deploy OSUser creattion .EXAMPLE Setup Server Environment withour OSUser and Credential file revise -------------------------------------------- read production-hoge.ps1 from c:\test. #> function Initialize-ValentiaEnvironment { [CmdletBinding(DefaultParameterSetName = "Server")] param ( [parameter(ParameterSetName = "Server")] [switch]$Server = $true, [parameter(ParameterSetName = "Client")] [switch]$Client = $false, [string]$HostUsage = "", [PSCredential]$Credential = $null, [string]$TrustedHosts = $valentia.wsman.TrustedHosts, [switch]$Force = $false, [switch]$NoOSUser = $false, [switch]$NoPassSave = $false, [switch]$NoReboot = $true, [switch]$SkipEnablePSRemoting = $false, [switch]$CredSSP = $false ) process { if ($PSBoundParameters.ContainsKey("Verbose")) { [ordered]@{ Server = $Server Client = $Client NoOSUser = $NoOSUser NoPassSave = $NoPassSave HostUsage = $HostUsage NoReboot = $NoReboot Force = $Force TrustedHosts = $TrustedHosts SkipEnablePSRemoting = $SkipEnablePSRemoting CredSSP = $CredSSP Credential = $Credential } } ExecutionPolicy FirewallNetWorkProfile if (-not($SkipEnablePSRemoting)) { if ($CredSSP) { DisablePSRemotingCredSSP } EnablePSRemoting -SkipEnablePSRemoting $SkipEnablePSRemoting -TrustedHosts $TrustedHosts WSManConfiguration if ($CredSSP) { EnableCredSSP -TrustedHosts $TrustedHosts } } IESettings $cred = CredentialCheck -NoOSUser $NoOSUser -NoPassSave $NoPassSave -credential $credential OSUserSetup -NoOSUser $NoOSUser -credential $cred ServerSetup -server $Server -credential $cred HostnameSetup -HostUsage $HostUsage RebootCheck -NoReboot $NoReboot -Force $Force } end { # Cleanup valentia Environment Invoke-ValentiaClean } begin { $ErrorActionPreference = $valentia.preference.ErrorActionPreference.custom Set-StrictMode -Version latest if(-not(Test-ValentiaPowerShellElevated)) { throw "Your PowerShell Console is not elevated! Must start PowerShell as an elevated to run this function because of UAC." } else { "Current session is already elevated, continue setup environment." | Write-ValentiaVerboseDebug } function ExecutionPolicy { Write-Host "Configuring ExecutionPolicy." -ForegroundColor Cyan "Set ExecutionPolicy to '{0}' only if execution policy is restricted." -f $valentia.ExecutionPolicy | Write-ValentiaVerboseDebug $executionPolicy = Get-ExecutionPolicy if ($executionPolicy -eq "Restricted") { Set-ExecutionPolicy $valentia.ExecutionPolicy -Force } } function FirewallNetWorkProfile { Write-Host "Configuring Firewall to accept PowerShell Remoting." -ForegroundColor Cyan if ([System.Environment]::OSVersion.Version -ge (New-Object 'Version' 6.2.0.0)) # over Win8/2012 { "Enable WindowsPowerShell Remoting Firewall Rule." | Write-ValentiaVerboseDebug New-ValentiaPSRemotingFirewallRule -PSRemotePort 5985 "Set FireWall Status from Public to Private." | Write-ValentiaVerboseDebug if ((Get-NetConnectionProfile).NetworkCategory -ne "DomainAuthenticated") { Set-NetConnectionProfile -NetworkCategory Private } } else { Write-Warning ("Your OS Version detected as '{0}', which is lower than 'Windows 8' or 'Windows Server 2012'. Skip setting Firewall rule and Network location." -f [System.Environment]::OSVersion.Version) } } function DisablePSRemotingCredSSP { Write-Host "Disabling PSRemoting and CredSSP" -ForegroundColor Cyan Start-Service winrm -PassThru winrm invoke restore winrm/config Disable-PSRemoting -Force Disable-WSManCredSSP -Role Client Disable-WSManCredSSP -Role Server Stop-Service winrm } function EnablePSRemoting ($TrustedHosts) { Write-Host "Enabling PSRemoting" -ForegroundColor Cyan "Setup PSRemoting" | Write-ValentiaVerboseDebug Start-Service winrm -PassThru Enable-PSRemoting -Force "Add $TrustedHosts hosts to trustedhosts" | Write-ValentiaVerboseDebug Enable-ValentiaWsManTrustedHosts -TrustedHosts $TrustedHosts "show winrm configuration result" | Write-ValentiaVerboseDebug winrm enumerate winrm/config/listener } function WSManConfiguration { Write-Host "Configure WSMan parameter." -ForegroundColor Cyan Set-ValetntiaWSManConfiguration } function EnableCredSSP ($TrustedHosts) { Write-Host "Enabling CredSSP" -ForegroundColor Cyan "Enable CredSSP for $TrustedHosts" | Write-ValentiaVerboseDebug Enable-ValentiaCredSSP -TrustedHosts $TrustedHosts "Enable winrm/Trustedhosts to registry AllowFreshCredentialsWhenNTLMOnly" | Write-ValentiaVerboseDebug Add-ValentiaCredSSPDelegateReg Add-ValentiaCredSSPDelegateRegKey Add-ValentiaCredSSPDelegateRegKeyProperty } function IESettings { Write-Host "Disable Enganced Security for Ineternet Explorer." -ForegroundColor Cyan "Disable Enhanced Security for Internet Explorer" | Write-ValentiaVerboseDebug Disable-ValentiaEnhancedIESecutiry } function CredentialCheck ($NoOSUser, $NoPassSave, [PSCredential]$credential = $null) { if ((-not $NoOSUser) -or (-not $NoPassSave)) { if ($null -ne $credential) { Write-Host "Credential information already passed. Skip Credential prompt." -ForegroundColor Cyan return $credential } else { Write-Host "Obtain PSCredential to set Credential information." -ForegroundColor Cyan return (Get-Credential -Credential $valentia.users.deployUser) } } } function OSUserSetup ($NoOSUser, $credential) { Write-Host "Adding Deploy User." -ForegroundColor Cyan if ($NoOSUser) { "NoOSUser switch was enabled, skipping create OSUser." | Write-ValentiaVerboseDebug } else { "Add valentia connection user" | Write-ValentiaVerboseDebug New-ValentiaOSUser -Credential $credential } } function ServerSetup ($server, $credential) { if ($Server) { Write-Host "Add valentia DeployFolder." -ForegroundColor Cyan New-ValentiaFolder "Set Valentia credential in Windows Credential Manager." | Write-ValentiaVerboseDebug # validation if ($NoPassSave){ "NoPassSave switch was enabled, skipping Create/Revise set password into Windows Credential Manager." | Write-ValentiaVerboseDebug; return; } if ($null -eq $credential){ "Credential was empty. Skipping Create/Revise set password into Windows Credential Manager." | Write-ValentiaVerboseDebug; return; } "Create Deploy user credential .pass" | Write-ValentiaVerboseDebug Set-ValentiaCredential -Credential $credential } } function HostnameSetup ($HostUsage) { Write-Host "Check HostName configuration." -ForegroundColor Cyan if ($HostUsage -eq "") { "skipping Set HostName." | Write-ValentiaVerboseDebug } else { "Update HostName." | Write-ValentiaVerboseDebug Set-ValentiaHostName -HostUsage $HostUsage } } function RebootCheck ($NoReboot, $Force) { Write-Host "Check Reboot status." -ForegroundColor Cyan if(Get-ValentiaRebootRequiredStatus) { if ($NoReboot) { Write-Host 'NoReboot switch was enabled, skipping reboot.' -ForegroundColor Cyan } elseif ($Force) { Write-Host "Start Restart Force." -ForegroundColor Cyan "Start Restart Force." | Write-ValentiaVerboseDebug Restart-Computer -Force:$Force } else { Write-Host "Start Restart with confirmation." -ForegroundColor Cyan "Start Restart with confirmation." | Write-ValentiaVerboseDebug Restart-Computer -Force:$Force -Confirm } } } } } # file loaded from path : \functions\Helper\Initialize\Initialize-ValentiaEnvironment.ps1 #Requires -Version 3.0 #-- Helper for valentia --# # go <# .SYNOPSIS Move location to valentia folder .DESCRIPTION You can specify branch path in configuration. If you changed from default, then change validation set for BranchPath for intellisence. .NOTES Author: guitarrapc Created: 13/Jul/2013 .EXAMPLE go -------------------------------------------- just move to root deployment path. .EXAMPLE go application -------------------------------------------- change location to BranchPath c:\deployment\application (in default configuration.) #> function Set-ValentiaLocation { [CmdletBinding()] param ( [Parameter(Position = 0, mandatory = $false, HelpMessage = "Select branch deploy folder to change directory.")] [ValentiaBranchPath]$BranchPath ) begin { $prevLocation = (Get-Location).Path $newlocation = Join-Path $valentia.RootPath ([ValentiaBranchPath]::$BranchPath) } process { # Move to BrachPath if exist ("moving to new location as '{0}' : '{1}'" -f $BranchPath, $newlocation) | Write-ValentiaVerboseDebug if (Test-Path $newlocation) { Set-Location -Path $newlocation } else { throw "Path not found exception! Make sure {0} is exist." -f $newlocation } } end { ("moved Location : '{0}', previous Location : '{1}'" -f (Get-Location).Path, $prevLocation) | Write-ValentiaVerboseDebug if ((Get-Location).Path -ne $prevLocation) { ("Location change to '{0}'" -f (Get-Location).Path) | Write-ValentiaVerboseDebug } else { Write-Warning "Location not changed." } } } # file loaded from path : \functions\Helper\Location\Set-ValentiaLocation.ps1 #Requires -Version 3.0 #-- Helper for valentia --# #-- Log Settings -- # <# .SYNOPSIS Setup Valentia Log Folder .DESCRIPTION Check Valentia Log folder and return log full path .NOTES Author: guitarrapc Created: 18/Sep/2013 .EXAMPLE New-ValentiaLog -LogFolder c:\logs\deployment -LogFile "hoge.log" -------------------------------------------- This is format sample. .EXAMPLE New-ValentiaLog -------------------------------------------- As New-ValentiaLog have default value in parameter, you do not required to specify log information #> function New-ValentiaLog { [CmdletBinding()] param ( [Parameter(Position = 0, mandatory = $false, HelpMessage = "Path to LogFolder.")] [string]$LogFolder = $(Join-Path $valentia.Log.path (Get-Date).ToString("yyyyMMdd")), [Parameter(Position = 1, mandatory = $false, HelpMessage = "Name of LogFile.")] [string]$LogFile = "$($valentia.Log.name)_$((Get-Date).ToString("yyyyMMdd_HHmmss"))_$([Guid]::NewGuid().ToString())$($valentia.Log.extension)" ) if (-not(Test-Path $LogFolder)) { ("LogFolder not found creating {0}" -f $LogFolder) | Write-ValentiaVerboseDebug New-Item -Path $LogFolder -ItemType Directory > $null } try { "Defining LogFile full path." | Write-ValentiaVerboseDebug $valentia.Log.fullPath = Join-Path $LogFolder $LogFile } catch { $SuccessStatus += $false $ErrorMessageDetail += $_ $ErrorCmdletName += ($MyInvocation.MyCommand).Name throw $_ } } # file loaded from path : \functions\Helper\Log\New-ValentiaLog.ps1 #Requires -Version 3.0 #-- Helper for valentia --# #-- End Result Execution -- # function Out-ValentiaResult { [CmdletBinding()] param ( [parameter(mandatory = $true)] [System.Diagnostics.Stopwatch]$StopWatch, [parameter(mandatory = $true)] [string]$Cmdlet, [parameter(mandatory = $false)] [string]$TaskFileName = "", [parameter(mandatory = $true)] [string[]]$DeployGroups, [parameter(mandatory = $true)] [bool]$SkipException, [parameter(mandatory = $true)] [bool]$Quiet ) # obtain Result $CommandResult = [ordered]@{ Success = !($valentia.Result.SuccessStatus -contains $false) TimeStart = $valentia.Result.TimeStart TimeEnd = (Get-Date).DateTime TotalDuration = $stopwatch.Elapsed.TotalSeconds Module = "$($MyInvocation.MyCommand.Module)" Cmdlet = $Cmdlet Alias = "$((Get-Alias | where ResolvedCommandName -eq $Cmdlet).Name)" TaskFileName = $TaskFileName ScriptBlock = "{0}" -f $valentia.Result.ScriptTorun DeployGroup = "{0}" -f "$($DeployGroups -join ', ')" TargetHostCount = $($valentia.Result.DeployMembers).count TargetHosts = "{0}" -f ($valentia.Result.DeployMembers -join ', ') Result = $valentia.Result.Result SkipException = $SkipException ErrorMessage = $($valentia.Result.ErrorMessageDetail | where {$_ -ne $null} | sort -Unique) } # show result WriteValentiaResultHost -quiet $Quiet -CommandResult $CommandResult # output result Log as json OutValentiaResultLog -CommandResult $CommandResult } # file loaded from path : \functions\Helper\Log\Out-ValentiaResult.ps1 #Requires -Version 3.0 #-- Helper for valentia --# # - Out Log and Host -# filter OutValentiaModuleLogHost { [CmdletBinding(DefaultParameterSetName = "message")] param ( [parameter(mandatory = $false, position = 0, valuefromPipeline = 1, ValuefromPipelineByPropertyName = 1)] [string]$logmessage, [parameter(mandatory = $false, position = 1)] [string]$logfile = $valentia.log.fullpath, [parameter(mandatory = $false, position = 2)] [Microsoft.PowerShell.Commands.FileSystemCmdletProviderEncoding]$encoding = $valentia.fileEncode, [parameter(mandatory = $false, position = 3, ParameterSetName = "message")] [switch]$message, [parameter(mandatory = $false, position = 3, ParameterSetName = "showdata")] [switch]$showdata, [parameter(mandatory = $false, position = 3, ParameterSetName = "hidedata")] [switch]$hidedata, [parameter(mandatory = $false, position = 3, ParameterSetName = "hidedataAsString")] [switch]$hidedataAsString, [parameter(mandatory = $false, position = 3, ParameterSetName = "warning")] [switch]$warning, [parameter(mandatory = $false, position = 3, ParameterSetName = "verbosing")] [switch]$verbosing, [parameter(mandatory = $false, position = 3, ParameterSetName = "error")] [switch]$error, [parameter(mandatory = $false, position = 3, ParameterSetName = "result")] [switch]$result, [parameter(mandatory = $false, position = 3, ParameterSetName = "resultAppend")] [switch]$resultAppend ) process { if($message) { $item = "[$(Get-Date)][message][$_]" Write-Host "$item" -ForegroundColor Cyan $item | Out-File -FilePath $logfile -Encoding $encoding -Append -Force -Width 1048 } elseif($showdata) { $_ $_ | Out-File -FilePath $logfile -Encoding $encoding -Append -Width 512 } elseif($hidedata) { $_ | Out-File -FilePath $logfile -Encoding $encoding -Append -Width 512 } elseif($hideDataAsString) { $item = "[$(Get-Date)][message][$_]" $item | Out-File -FilePath $logfile -Encoding $encoding -Append -Force -Width 1048 } elseif($warning) { Write-Warning $_ $_ | Out-File -FilePath $logfile -Encoding $encoding -Append -Width 512 } elseif($verbosing) { Write-Verbose $_ $_ | Out-File -FilePath $logfile -Encoding $encoding -Append -Width 512 } elseif($error) { $_ | Out-File -FilePath $logfile -Encoding $encoding -Append -Width 512 } elseif($result) { $_ | Out-File -FilePath $logfile -Encoding $encoding -Force -Width 1048 } elseif($resultAppend) { $_ | Out-File -FilePath $logfile -Encoding $encoding -Force -Width 1048 -Append } } } # file loaded from path : \functions\Helper\Log\Private\OutValentiaModuleLogHost.ps1 #Requires -Version 3.0 #-- Helper for valentia --# #-- Log Output Result Settings -- # function OutValentiaResultLog { [CmdletBinding()] param ( [parameter(mandatory = $true)] [System.Collections.Specialized.OrderedDictionary]$CommandResult, [parameter(mandatory = $false)] [string]$removeProperty = "Result", [bool]$Append = $false ) try { $json = $CommandResult | ConvertTo-Json } catch { $json = $CommandResult.Remove($removeProperty) | ConvertTo-Json } finally { if ($Append) { $json | OutValentiaModuleLogHost -resultAppend } else { $json | OutValentiaModuleLogHost -result } } } # file loaded from path : \functions\Helper\Log\Private\OutValentiaResultLog.ps1 #Requires -Version 3.0 #-- Helper for valentia --# #-- Log Output Result Settings -- # function WriteValentiaResultHost { [CmdletBinding()] param ( [parameter(mandatory = $true)] [bool]$quiet, [parameter(mandatory = $true)] [System.Collections.Specialized.OrderedDictionary]$CommandResult ) if (-not $quiet) { # Show Stopwatch for Total section Write-Verbose ("`t`tTotal duration Second`t: {0}" -f $CommandResult.TotalDuration) [PSCustomObject]$CommandResult } else { ([PSCustomObject]$Commandresult).Success } } # file loaded from path : \functions\Helper\Log\Private\WriteValentiaResultHost.ps1 #Requires -Version 3.0 #-- Public Module Functions to load Task --# # Task <# .SYNOPSIS Execute Task and push into CurrentContext .NOTES Author: guitarrapc Created: 31/July/2014 .EXAMPLE Push-ValentiaCurrentContextToTask -ScriptBlock $scriptBlock -TaskFileName $TaskFileName #> function Push-ValentiaCurrentContextToTask { [CmdletBinding()] param ( [parameter(mandatory = $false)] [ScriptBlock]$ScriptBlock, [parameter(mandatory = $false)] [string]$TaskFileName ) # Swtich ScriptBlock or ScriptFile was selected switch ($true) { {$ScriptBlock} { # run Task with ScriptBlock ("ScriptBlock parameter [ {0} ] was selected." -f $ScriptBlock) | Write-ValentiaVerboseDebug $taskkey = Task -name ScriptBlock -action $ScriptBlock # Read Current Context $currentContext = $valentia.context.Peek() } {$TaskFileName} { # check file exist or not if (-not(Test-Path (Join-Path (Get-Location).Path $TaskFileName))) { $TaskFileStatus = [PSCustomObject]@{ ErrorMessageDetail = "TaskFileName '{0}' not found in '{1}' exception!!" -f $TaskFileName,(Join-Path (Get-Location).Path $TaskFileName) SuccessStatus = $false } $valentia.Result.SuccessStatus += $TaskFileStatus.SuccessStatus $valentia.Result.ErrorMessageDetail += $TaskFileStatus.ErrorMessageDetail } # Read Task File and get Action to run ("TaskFileName parameter '{0}' was selected." -f $TaskFileName) | Write-ValentiaVerboseDebug # run Task $TaskFileName inside functions and obtain scriptblock written in. $taskkey = & $TaskFileName # Read Current Context $currentContext = $valentia.context.Peek() } default { $valentia.Result.SuccessStatus += $false $valentia.Result.ErrorMessageDetail += "TaskFile or ScriptBlock parameter must not be null" throw "TaskFile or ScriptBlock parameter must not be null" } } return $currentContext.tasks.$taskKey } # file loaded from path : \functions\Helper\Prerequisites\Private\Push-ValentiaCurrentContextToTask.ps1 #Requires -Version 3.0 #-- Helper for valentia Invokation Prerequisite setup--# function Set-ValentiaInvokationPrerequisites { [CmdletBinding()] param ( [parameter(mandatory = $true)] [System.Diagnostics.Stopwatch]$StopWatch, [Parameter(Position = 0, mandatory = $true)] [string[]]$DeployGroups, [Parameter(Position = 1, mandatory = $false)] [string]$TaskFileName, [Parameter(Position = 2, mandatory = $false)] [ScriptBlock]$ScriptBlock, [Parameter(Position = 3, mandatory = $false)] [string]$DeployFolder, [Parameter(Position = 4, mandatory = $false)] [string[]]$TaskParameter ) # clear previous result Invoke-ValentiaCleanResult # Initialize Error status $valentia.Result.SuccessStatus = $valentia.Result.ErrorMessageDetail = @() # Get Start Time $valentia.Result.TimeStart = (Get-Date).DateTime # Import default Configurations $valeWarningMessages.warn_import_configuration | Write-ValentiaVerboseDebug Import-ValentiaConfiguration # Import default Modules $valeWarningMessages.warn_import_modules | Write-ValentiaVerboseDebug Import-valentiaModules # Log Setting New-ValentiaLog # Set Task and push CurrentContext $task = Push-ValentiaCurrentContextToTask -ScriptBlock $ScriptBlock -TaskFileName $TaskFileName # Set Task as CurrentContext with task key $valentia.Result.ScriptTorun = $task.Action # Obtain DeployMember IP or Hosts for deploy try { "Get host addresses to connect." | Write-ValentiaVerboseDebug $valentia.Result.DeployMembers = Get-valentiaGroup -DeployFolder $DeployFolder -DeployGroup $DeployGroups } catch { $valentia.Result.SuccessStatus += $false $valentia.Result.ErrorMessageDetail += $_ Write-Error $_ } # Show Stopwatch for Begin section Write-Verbose ("{0}Duration Second for Begin Section: {1}" -f "`t`t", $Stopwatch.Elapsed.TotalSeconds) } # file loaded from path : \functions\Helper\Prerequisites\Private\Set-ValentiaInvokationPrerequisites.ps1 #Requires -Version 3.0 # -- helper function -- # <# .SYNOPSIS Show valentia Prompt For Choice description and will return item you passed. .DESCRIPTION You can show choice Description with your favored items. .NOTES Author: guitarrapc Created: 17/Nov/2013 .EXAMPLE Show-ValentiaPromptForChoice -------------------------------------------- default will use what you have written in valentia-config.ps1 .EXAMPLE Show-ValentiaPromptForChoice -questionHelps $(Show-ValentiaGroup).Name -------------------------------------------- Will check valentia deploy folder and get deploygroup files. You can see choice description for each deploygroup file, and will get which item was selected. #> function Show-ValentiaPromptForChoice { [CmdletBinding()] param ( # input prompt items with array. second index is for help message. [parameter(mandatory = $false, position = 0)] [string[]]$questions = $valentia.promptForChoice.questions, # input title message showing when prompt. [parameter(mandatory = $false, position = 1)] [string[]]$title = $valentia.promptForChoice.title, # input message showing when prompt. [parameter(mandatory = $false, position = 2)] [string]$message = $valentia.promptForChoice.message, # input additional message showing under message. [parameter(mandatory = $false, position = 3)] [string]$additionalMessage = $valentia.promptForChoice.additionalMessage, # input Index default selected when prompt. [parameter(mandatory = $false, position = 4)] [int]$defaultIndex = $valentia.promptForChoice.defaultIndex ) $ErrorActionPreference = $valentia.preference.ErrorActionPreference.custom try { # create caption Messages if(-not [string]::IsNullOrEmpty($additionalMessage)) { $message += ([System.Environment]::NewLine + $additionalMessage) } # create dictionary include dictionary <int, KV<string, string>> : accessing KV <string, string> with int key return from prompt $script:dictionary = New-Object 'System.Collections.Generic.Dictionary[int, System.Collections.Generic.KeyValuePair[string, string]]' foreach ($question in $questions) { if ("$questions" -eq "$($valentia.promptForChoice.questions)") { if ($private:count -eq 1) { # create key to access value $private:key = $valentia.promptForChoice.defaultChoiceNo } else { # create key to access value $private:key = $valentia.promptForChoice.defaultChoiceYes } } else { # create key to access value $private:key = [System.Text.Encoding]::ASCII.GetString($([byte[]][char[]]'a') + [int]$private:count) } # create KeyValuePair<string, string> for prompt item : accessing value with 1 letter Alphabet by converting char $script:keyValuePair = New-Object 'System.Collections.Generic.KeyValuePair[string, string]'($key, $question) # add to Dictionary $dictionary.Add($count, $keyValuePair) # increment to next char $count++ # prompt limit to max 26 items as using single Alphabet charactors. if ($count -gt 26) { throw ("Not allowed to pass more then '{0}' items for prompt" -f ($dictionary.Keys).count) } } # create choices Collection $script:collectionType = [System.Management.Automation.Host.ChoiceDescription] $script:choices = New-Object "System.Collections.ObjectModel.Collection[$CollectionType]" # create choice description from dictionary<int, KV<string, string>> foreach ($dict in $dictionary.GetEnumerator()) { foreach ($kv in $dict) { # create prompt choice item. Currently you could not use help message. $private:choice = (("{0} (&{1}){2}-" -f $kv.Value.Value, "$($kv.Value.Key)".ToUpper(), [Environment]::NewLine), ($valentia.promptForChoice.helpMessage -f $kv.Value.Key, $kv.Value.Value)) # add to choices $choices.Add((New-Object $CollectionType $choice)) } } # show choices on host $script:answer = $host.UI.PromptForChoice($title, $message, $choices, $defaultIndex) # return value from key return ($dictionary.GetEnumerator() | where Key -eq $answer).Value.Value } catch { throw $_ } } # file loaded from path : \functions\Helper\PromptForChoice\Show-ValentiaPromptForChoice.ps1 #Requires -Version 3.0 #-- Scheduler Task Functions --# <# .SYNOPSIS Extension to Disable TaskScheduler Log Status .DESCRIPTION You can change TaskScheduler Log to State => Enable Make sure Log affect to all TaskScheduler. .NOTES Author: guitarrapc Created: 19/Sep/2014 .EXAMPLE Disable-ValentiaScheduledTaskLogSetting .LINK https://github.com/guitarrapc/valentia/wiki/TaskScheduler-Automation #> function Disable-ValentiaScheduledTaskLogSetting { [CmdletBinding()] param() begin { $ErrorMessages = Data { ConvertFrom-StringData -StringData @" LogOperationNotPermitted = "Attempted to perform an unauthorized operation. You must elevate PowerShell Session to Change TaskSchedulerLog setting." "@ } } end { if (-not(Test-ValentiaPowerShellElevated)){ throw New-Object System.UnauthorizedAccessException ($ErrorMessages.LogOperationNotPermitted) } try { $logName = 'Microsoft-Windows-TaskScheduler/Operational' $log = New-Object System.Diagnostics.Eventing.Reader.EventLogConfiguration $logName $log.IsEnabled = $false $log.SaveChanges() } finally { $log.Dispose() } } } # file loaded from path : \functions\Helper\ScheduledTask\Disable-ValentiaScheduledTaskLogSetting.ps1 #Requires -Version 3.0 #-- Scheduler Task Functions --# <# .SYNOPSIS Extension to Enable TaskScheduler Log Status .DESCRIPTION You can change TaskScheduler Log to State => Enable Make sure Log affect to all TaskScheduler. .NOTES Author: guitarrapc Created: 19/Sep/2014 .EXAMPLE Enable-ValentiaScheduledTaskLogSetting .LINK https://github.com/guitarrapc/valentia/wiki/TaskScheduler-Automation #> function Enable-ValentiaScheduledTaskLogSetting { [CmdletBinding()] param() begin { $ErrorMessages = Data { ConvertFrom-StringData -StringData @" LogOperationNotPermitted = "Attempted to perform an unauthorized operation. You must elevate PowerShell Session to Change TaskSchedulerLog setting." "@ } } end { if (-not(Test-ValentiaPowerShellElevated)){ throw New-Object System.UnauthorizedAccessException ($ErrorMessages.LogOperationNotPermitted) } try { $logName = 'Microsoft-Windows-TaskScheduler/Operational' $log = New-Object System.Diagnostics.Eventing.Reader.EventLogConfiguration $logName $log.IsEnabled = $true $log.SaveChanges() } finally { $log.Dispose() } } } # file loaded from path : \functions\Helper\ScheduledTask\Enable-ValentiaScheduledTaskLogSetting.ps1 #Requires -Version 3.0 #-- Scheduler Task Functions --# <# .SYNOPSIS Extension to set TaskScheduler and Unregister Task you selected. .DESCRIPTION You can remove task and Empty folder if desired. .NOTES Author: guitarrapc Created: 24/Sep/2014 .EXAMPLE $param = @{ taskName = "hoge" Description = "None" taskPath = "\fuga" execute = "powershell.exe" Argument = '-Command "Get-Date | out-File c:\task01.log"' ScheduledAt = [datetime]"00:30:00" Once = $true Hidden = $true Disable = $false Force = $true Runlevel = "limited" } Set-ValentiaScheduledTask @param Remove-ValentiaScheduledTask -taskName $param.taskName -taskPath $param.taskPath # remove Task from your selected path .EXAMPLE $param = @{ taskName = "hoge" Description = "None" taskPath = "\fuga" execute = "powershell.exe" Argument = '-Command "Get-Date | out-File c:\task01.log"' ScheduledAt = [datetime]"00:30:00" Once = $true Hidden = $true Disable = $false Force = $true Runlevel = "limited" } Set-ValentiaScheduledTask @param Remove-ValentiaScheduledTask -taskName $param.taskName -taskPath $param.taskPath -RemoveEmptyFolder $true # remove Task and Empty Folder .EXAMPLE $param = @{ taskName = "hoge" Description = "None" taskPath = "\fuga" execute = "powershell.exe" Argument = '-Command "Get-Date | out-File c:\task01.log"' ScheduledAt = [datetime]"00:30:00" Once = $true Hidden = $true Disable = $false Force = $true Runlevel = "limited" } Set-ValentiaScheduledTask @param Get-ScheduledTask -TaskName hoge -TaskPath \fuga\ | Remove-ValentiaScheduledTask # Remove ScheduledTask passed as CIMInstance .LINK https://github.com/guitarrapc/valentia/wiki/TaskScheduler-Automation #> function Remove-ValentiaScheduledTask { [CmdletBinding(DefaultParameterSetName="TaskName")] param ( [parameter(mandatory = $true, Position = 0, ParameterSetName = "TaskName", ValueFrompipelineByPropertyName = 1)] [string]$taskName, [parameter(mandatory = $false, Position = 1, ParameterSetName = "TaskName", ValueFrompipelineByPropertyName = 1)] [string]$taskPath = "\", [parameter(mandatory = $false, Position = 1, ParameterSetName = "CimTask", ValueFrompipeline = 1)] [CimInstance[]]$InputObject, [parameter(mandatory = $false, Position = 2)] [bool]$RemoveEmptyFolder = $false, [parameter(mandatory = $false, Position = 3)] [bool]$Force = $false ) end { $Confirm = !$Force if ($PSBoundParameters.ContainsKey('taskName')) { # exist $existingTaskParam = @{ TaskName = $taskName TaskPath = ValidateTaskPathLastChar -taskPath $taskPath } # Unregister Task $task = GetExistingTaskScheduler @existingTaskParam if (($task | measure).count -eq 0) { Write-Verbose ($VerboseMessages.TaskNotFound -f $existingTaskParam.taskName, $existingTaskParam.taskPath) } else { Write-Verbose ($VerboseMessages.RemoveTask -f $existingTaskParam.taskName, $existingTaskParam.taskPath) $task | Unregister-ScheduledTask -PassThru -Confirm:$Confirm } } else { $InputObject | Unregister-ScheduledTask -PassThru -Confirm:$confirm } # Remove Empty task folder if ($RemoveEmptyFolder){ Remove-ValentiaScheduledTaskEmptyDirectoryPath } } begin { $VerboseMessages = Data { ConvertFrom-StringData -StringData @" RemoveTask = "Removing Task Scheduler Name '{0}', Path '{1}'" TaskNotFound = "Task not found for TaskName '{0}', TaskPath '{1}'. Skip execution." "@ } function GetExistingTaskScheduler ($TaskName, $TaskPath) { $task = Get-ScheduledTask | where TaskName -eq $taskName | where TaskPath -eq $taskPath return $task } function ValidateTaskPathLastChar ($taskPath) { $lastChar = [System.Linq.Enumerable]::ToArray($taskPath) | select -Last 1 if ($lastChar -ne "\"){ return $taskPath + "\" } return $taskPath } } } # file loaded from path : \functions\Helper\ScheduledTask\Remove-ValentiaScheduledTask.ps1 #Requires -Version 3.0 #-- Scheduler Task Functions --# <# .SYNOPSIS Extension to set TaskScheduler and Remove Task folder where Task not exist .DESCRIPTION You can remove task Empty folder. Normal Unregister Cmdlet never erase them and it may cause some issue like TaskScheduler could not name as same as child folder of TaskPath. You can not create hoge task in root (\) when there are \hoge\ folder. \ -> \hoge\ -> \Microsoft\ .NOTES Author: guitarrapc Created: 24/Sep/2014 .EXAMPLE $param = @{ taskName = "hoge" Description = "None" taskPath = "\fuga" execute = "powershell.exe" Argument = '-Command "Get-Date | out-File c:\task01.log"' ScheduledAt = [datetime]"00:30:00" Once = $true Hidden = $true Disable = $false Force = $true Runlevel = "limited" } Set-ValentiaScheduledTask @param Remove-ValentiaScheduledTask -taskName $param.taskName -taskPath $param.taskPath Remove-ValentiaScheduledTaskEmptyDirectoryPath # Remove task not exist any task or taskfolder. .LINK https://github.com/guitarrapc/valentia/wiki/TaskScheduler-Automation #> function Remove-ValentiaScheduledTaskEmptyDirectoryPath { # validate target Directory is existing $path = Join-Path $env:windir "System32\Tasks" $result = Get-ChildItem -Path $path -Directory | where Name -ne "Microsoft" if (($result | measure).count -eq 0){ return; } # validate Child is blank $result.FullName ` | where {(Get-ChildItem -Path $_) -eq $null} ` | Remove-Item -Force } # file loaded from path : \functions\Helper\ScheduledTask\Remove-ValentiaScheduledTaskEmptyDirectoryPath.ps1 #Requires -Version 3.0 #-- Scheduler Task Functions --# <# .SYNOPSIS Extension to set TaskScheduler and define them as enumerable. .DESCRIPTION You can pass several task scheduler definition at once. .NOTES Author: guitarrapc Created: 11/Aug/2014 .EXAMPLE $param = @{ taskName = "Sample Repeatable Task" Description = "None" taskPath = "\" execute = "PATH TO EXE" Argument = '' ScheduledAt = [datetime]::Now ScheduledTimeSpan = (New-TimeSpan -Minutes 5) ScheduledDuration = ([TimeSpan]::MaxValue) Hidden = $true Disable = $false Force = $true }, @{ taskName = "Sample Daily Task" Description = "None" taskPath = "\" execute = "PATH TO EXE" Argument = '' ScheduledAt = [datetime]"00:00:00" Daily = $true Hidden = $true Disable = $false Force = $true }, @{ taskName = "Sample OneTime Task" Description = "None" taskPath = "\" execute = "PATH TO EXE" Argument = '' ScheduledAt = [datetime]"00:30:00" Once = $true Hidden = $true Disable = $false Force = $true } $Credential = Get-ValentiaCredential foreach ($p in $param.GetEnumerator()) { Set-ValentiaScheduledTask @p -Credential $Credential } # Multipole task With Credential .EXAMPLE $param = @{ taskName = "Sample No Credential Task" Description = "None" taskPath = "\" execute = "PATH TO EXE" Argument = '' ScheduledAt = [datetime]::Now ScheduledTimeSpan = (New-TimeSpan -Minutes 5) ScheduledDuration = ([TimeSpan]::MaxValue) Hidden = $true Disable = $false Force = $true } Set-ValentiaScheduledTask @param # single task without credential .EXAMPLE $param = @{ taskName = "Sample High Runlevel without Credential Task" Description = "None" taskPath = "\" execute = "PATH TO EXE" Argument = '' ScheduledAt = [datetime]::Now ScheduledTimeSpan = (New-TimeSpan -Minutes 5) ScheduledDuration = ([TimeSpan]::MaxValue) Hidden = $true Disable = $false Force = $true RunLevel = "Highest" } Set-ValentiaScheduledTask @param # single task without credential and set Runlevel High .EXAMPLE $param = @{ taskName = "Sample High Runlevel with Credential Task" Description = "None" taskPath = "\" execute = "PATH TO EXE" Argument = '' ScheduledAt = [datetime]::Now ScheduledTimeSpan = (New-TimeSpan -Minutes 5) ScheduledDuration = ([TimeSpan]::MaxValue) Hidden = $true Disable = $false Force = $true RunLevel = "Highest" } $Credential = Get-ValentiaCredential Set-ValentiaScheduledTask @param -Credential $Credential # single task with credential and set Runlevel High .LINK https://github.com/guitarrapc/valentia/wiki/TaskScheduler-Automation #> function Set-ValentiaScheduledTask { [CmdletBinding(DefaultParameterSetName = "ScheduledDuration")] param ( [parameter(mandatory = $false, Position = 0)] [string]$Execute, [parameter(mandatory = $false, Position = 1)] [string]$Argument = "", [parameter(mandatory = $false, Position = 2)] [string]$WorkingDirectory = "", [parameter(mandatory = $true, Position = 3)] [string]$TaskName, [parameter(mandatory = $false, Position = 4)] [string]$TaskPath = "\", [parameter(mandatory = $false, Position = 5)] [datetime[]]$ScheduledAt, [parameter(mandatory = $false, Position = 6, parameterSetName = "ScheduledDuration")] [TimeSpan[]]$ScheduledTimeSpan = ([TimeSpan]::FromHours(1)), [parameter(mandatory = $false, Position = 7, parameterSetName = "ScheduledDuration")] [TimeSpan[]]$ScheduledDuration = [TimeSpan]::MaxValue, [parameter(mandatory = $false, Position = 8, parameterSetName = "Daily")] [bool]$Daily = $false, [parameter(mandatory = $false, Position = 9, parameterSetName = "Once")] [bool]$Once = $false, [parameter(mandatory = $false, Position = 10)] [string]$Description, [parameter(mandatory = $false, Position = 11)] [PScredential]$Credential = $null, [parameter(mandatory = $false, Position = 12)] [bool]$Disable = $true, [parameter(mandatory = $false, Position = 13)] [bool]$Hidden = $true, [parameter(mandatory = $false, Position = 14)] [TimeSpan]$ExecutionTimeLimit = ([TimeSpan]::FromDays(3)), [parameter(mandatory = $false,Position = 15)] [ValidateSet("At", "Win8", "Win7", "Vista", "V1")] [string]$Compatibility = "Win8", [parameter(mandatory = $false,Position = 16)] [ValidateSet("Highest", "Limited")] [string]$Runlevel = "Limited", [parameter(mandatory = $false, Position = 17)] [bool]$Force = $false ) end { Write-Verbose ($VerboseMessages.CreateTask -f $TaskName, $TaskPath) # exist $existingTaskParam = @{ TaskName = $TaskName TaskPath = $TaskPath } $currentTask = GetExistingTaskScheduler @existingTaskParam #region Exclude Action Change : Only Disable / Enable Task if (($Execute -eq "") -and (TestExistingTaskScheduler -Task $currentTask)) { EnableDisableScheduleTask -Disable $Disable return; } #endregion #region Include Action Change # credential if($Credential -ne $null) { # Credential $credentialParam = @{ User = $Credential.UserName Password = $Credential.GetNetworkCredential().Password } # Principal $principalParam = @{ UserId = $Credential.UserName RunLevel = $Runlevel LogOnType = "InteractiveOrPassword" } } # validation if ($Execute -eq ""){ throw New-Object System.InvalidOperationException ($ErrorMessages.ExecuteBrank) } if (Test-ValentiaPowerShellElevated) { if (TestExistingTaskSchedulerWithPath @existingTaskParam) { throw New-Object System.InvalidOperationException ($ErrorMessages.SameNameFolderFound -f $taskName) } } # Action $actionParam = @{ Argument = $Argument Execute = $Execute WorkingDirectory = $WorkingDirectory } # trigger $triggerParam = @{ ScheduledTimeSpan = $scheduledTimeSpan ScheduledDuration = $scheduledDuration ScheduledAt = $ScheduledAt Daily = $Daily Once = $Once } # Description if ($Description -eq ""){ $Description = "No Description"} # Setup Task items $action = CreateTaskSchedulerAction @actionParam $trigger = CreateTaskSchedulerTrigger @triggerParam $settings = New-ScheduledTaskSettingsSet -Disable:$Disable -Hidden:$Hidden -Compatibility $Compatibility -ExecutionTimeLimit $ExecutionTimeLimit $registerParam = if ($null -ne $Credential) { Write-Verbose $VerboseMessages.UsePrincipal $principal = New-ScheduledTaskPrincipal @principalParam $scheduledTask = New-ScheduledTask -Description $Description -Action $action -Settings $settings -Trigger $trigger -Principal $principal @{ InputObject = $scheduledTask TaskName = $TaskName TaskPath = $TaskPath Force = $Force } } else { Write-Verbose $VerboseMessages.SkipPrincipal @{ Action = $action Settings = $settings Trigger = $trigger Description = $Description TaskName = $TaskName TaskPath = $TaskPath Runlevel = $Runlevel Force = $Force } } # Register if ($force -or -not(TestExistingTaskScheduler -Task $currentTask)) { if ($null -ne $Credential) { Register-ScheduledTask @registerParam @credentialParam return; } else { Register-ScheduledTask @registerParam return; } } #endregion } begin { $ErrorMessages = Data { ConvertFrom-StringData -StringData @" InvalidTrigger = "Invalid Operation detected, you can't set same or greater timespan for RepetitionInterval '{0}' than RepetitionDuration '{1}'." ExecuteBrank = "Invalid Operation detected, Execute detected as blank. You must set executable string." SameNameFolderFound = "Already same FolderName existing as TaskPath : \\{0}\\ . Please change TaskName or Rename TaskFolder.." "@ } $VerboseMessages = Data { ConvertFrom-StringData -StringData @" CreateTask = "Creating Task Scheduler Name '{0}', Path '{1}'" UsePrincipal = "Using principal with Credential. Execution will be fail if not elevated." SkipPrincipal = "Skip Principal and Credential. Runlevel Highest requires elevated." "@ } $WarningMessages = Data { ConvertFrom-StringData -StringData @" TaskAlreadyExist = '"{0}" already exist on path "{1}". Please Set "-Force $true" to overwrite existing task.' "@ } function GetExistingTaskScheduler ($TaskName, $TaskPath) { return Get-ScheduledTask | where TaskName -eq $taskName | where TaskPath -eq $taskPath } function TestExistingTaskScheduler ($Task) { $result = ($task | Measure-Object).count -ne 0 if ($result){ Write-Verbose ($WarningMessages.TaskAlreadyExist -f $task.taskName, $task.taskPath) } return $result } function TestExistingTaskSchedulerWithPath ($TaskName, $TaskPath) { if ($TaskPath -ne "\"){ return $false } # only run when taskpath is \ $path = Join-Path $env:windir "System32\Tasks" $result = Get-ChildItem -Path $path -Directory | where Name -eq $TaskName if (($result | measure).count -ne 0) { return $true } return $false } function CreateTaskSchedulerAction ($Argument, $Execute, $WorkingDirectory) { if (($Argument -eq "") -and ($WorkingDirectory -eq "")) { return New-ScheduledTaskAction -Execute $execute } if (($Argument -ne "") -and ($WorkingDirectory -eq "")) { return New-ScheduledTaskAction -Execute $Execute -Argument $Argument } if (($Argument -ne "") -and ($WorkingDirectory -ne "")) { return New-ScheduledTaskAction -Execute $Execute -Argument $Argument -WorkingDirectory $WorkingDirectory } } function CreateTaskSchedulerTrigger ($ScheduledTimeSpan, $ScheduledDuration, $ScheduledAt, $Daily, $Once) { $trigger = if (($false -eq $Daily) -and ($false -eq $Once)) { $ScheduledTimeSpanPair = New-ValentiaZipPairs -first $ScheduledTimeSpan -Second $ScheduledDuration $ScheduledAtPair = New-ValentiaZipPairs -first $ScheduledAt -Second $ScheduledTimeSpanPair $ScheduledAtPair ` | %{ if ($_.Item2.Item1 -ge $_.Item2.Item2){ throw New-Object System.InvalidOperationException ($ErrorMessages.InvalidTrigger -f $_.Item2.Item1, $_.Item2.Item2)} New-ScheduledTaskTrigger -At $_.Item1 -RepetitionInterval $_.Item2.Item1 -RepetitionDuration $_.Item2.Item2 -Once } } elseif ($Daily) { $ScheduledAt | %{New-ScheduledTaskTrigger -At $_ -Daily} } elseif ($Once) { $ScheduledAt | %{New-ScheduledTaskTrigger -At $_ -Once} } return $trigger } function EnableDisableScheduleTask { [OutputType([Void])] [CmdletBinding()] param ( [bool]$Disable ) switch ($Disable) { $true { $currentTask | Disable-ScheduledTask return; } $false { $currentTask | Enable-ScheduledTask return; } } } } } # file loaded from path : \functions\Helper\ScheduledTask\Set-ValentiaScheduledTask.ps1 #Requires -Version 3.0 #-- Scheduler Task Functions --# <# .SYNOPSIS Test is TaskScheduler is same prameter. .DESCRIPTION You can test is scheduled task setting is desired. .NOTES Author: guitarrapc Created: 23/Feb/2015 .EXAMPLE $param = @{ Execute = "powershell.exe" TaskName = "hoge" ScheduledAt = [datetime]"2015/1/1 0:0:0" Once = $true } Set-ValentiaScheduledTask @param -Force $true Test-ValentiaScheduledTask ` -TaskName hoge ` -Execute "powershell.exe" -Verbose ` # This example is minimum testing and will return $true # None passed parameter will skip checking .EXAMPLE Test-ValentiaScheduledTask ` -TaskName hoge ` -Execute "powershell.exe" ` -ScheduledAt ([datetime]"2015/01/1 0:0:0") ` -Once $true # You can add parameter for strict parameter checking. .EXAMPLE $param = @{ Execute = "powershell.exe" Argument = "-Command ''" WorkingDirectory = "" Description = "hoge" TaskName = "hoge" TaskPath = "\hoge\" ScheduledAt = [datetime]"2015/1/1 0:0:0" #Daily = $true Once = $true Disable = $true Hidden = $true Credential = Get-ValentiaCredential } Set-ValentiaScheduledTask @param -Force $true Test-ValentiaScheduledTask ` -TaskName hoge ` -TaskPath "\hoge\" ` -Execute "powershell.exe" ` -Argument "-Command ''" ` -Description hoge ` -Credential (Get-ValentiaCredential) ` -ScheduledAt ([datetime]"2015/01/1 0:0:0") ` -Once $true # Testing scheduled task would return true .EXAMPLE Test-ValentiaScheduledTask ` -TaskName hoge ` -TaskPath "\hoge\" ` -Execute "powershell.exe" ` -Argument "-Command ''" ` -Description hoge ` -Credential (Get-ValentiaCredential) ` -ScheduledAt ([datetime]"2015/01/1 0:0:0") ` -Daily $true -Debug -Verbose # Testing scheduled task would return false as Daily is invalid. (Should check Once). # You can check progress with -Debug and -Verbose switch .LINK https://github.com/guitarrapc/valentia/wiki/TaskScheduler-Automation #> function Test-ValentiaScheduledTask { [OutputType([bool])] [CmdletBinding(DefaultParameterSetName = "ScheduledDuration")] param ( [parameter(mandatory = $true, Position = 0)] [string]$TaskName, [parameter(mandatory = $false, Position = 1)] [string]$TaskPath = "\", [parameter(mandatory = $false, Position = 2)] [string]$Execute, [parameter(mandatory = $false, Position = 3)] [string]$Argument, [parameter(mandatory = $false, Position = 4)] [string]$WorkingDirectory, [parameter(mandatory = $false, Position = 5)] [datetime[]]$ScheduledAt, [parameter(mandatory = $false, Position = 6, parameterSetName = "ScheduledDuration")] [TimeSpan[]]$ScheduledTimeSpan, [parameter(mandatory = $false, Position = 7, parameterSetName = "ScheduledDuration")] [TimeSpan[]]$ScheduledDuration, [parameter(mandatory = $false, Position = 8, parameterSetName = "Daily")] [bool]$Daily = $false, [parameter(mandatory = $false, Position = 9, parameterSetName = "Once")] [bool]$Once = $false, [parameter(mandatory = $false, Position = 10)] [string]$Description, [parameter(mandatory = $false, Position = 11)] [PScredential]$Credential, [parameter(mandatory = $false, Position = 12)] [bool]$Disable, [parameter(mandatory = $false, Position = 13)] [bool]$Hidden, [parameter(mandatory = $false, Position = 14)] [TimeSpan]$ExecutionTimeLimit = [TimeSpan]::FromDays(3), [parameter(mandatory = $false,Position = 15)] [ValidateSet("At", "Win8", "Win7", "Vista", "V1")] [string]$Compatibility, [parameter(mandatory = $false,Position = 16)] [ValidateSet("Highest", "Limited")] [string]$Runlevel ) begin { function GetScheduledTask { [OutputType([HashTable])] [CmdletBinding()] param ( [parameter(Mandatory = $true)] [Microsoft.Management.Infrastructure.CimInstance[]]$ScheduledTask, [parameter(Mandatory = $true)] [string]$Parameter, [parameter(Mandatory = $true)] [string]$Value ) Write-Debug ("Checking {0} is exists with : {1}" -f $parameter, $Value) $task = $root | where $Parameter -eq $Value $uniqueValue = $task.$Parameter | sort -Unique $result = $uniqueValue -eq $Value Write-Verbose ("{0} : {1} ({2})" -f $Parameter, $result, $uniqueValue) return @{ task = $task result = $result } } function TestScheduledTask { [OutputType([bool])] [CmdletBinding()] param ( [parameter(Mandatory = $true)] [Microsoft.Management.Infrastructure.CimInstance]$ScheduledTask, [parameter(Mandatory = $true)] [ValentiaScheduledParameterType]$Type, [parameter(Mandatory = $true)] [string]$Parameter, [parameter(Mandatory = $false)] [PSObject]$Value, [bool]$IsExist ) # skip when Parameter not use if ($IsExist -eq $false) { Write-Debug ("Skipping {0} as value not passed to function." -f $Parameter) return $true } # skip null if ($Value -eq $null) { Write-Debug ("Skipping {0} as passed value '{1}' is null." -f $Parameter, $Value) return $true } Write-Debug ("Checking {0} is match with : {1}" -f $Parameter, $Value) $target = switch ($Type) { ([ValentiaScheduledParameterType]::Root) { $ScheduledTask.$Parameter | sort -Unique } ([ValentiaScheduledParameterType]::Actions) { $ScheduledTask.Actions.$Parameter | sort -Unique } ([ValentiaScheduledParameterType]::Principal) { $ScheduledTask.Principal.$Parameter | sort -Unique } ([ValentiaScheduledParameterType]::Settings) { $ScheduledTask.Settings.$Parameter | sort -Unique } ([ValentiaScheduledParameterType]::Triggers) { $ScheduledTask.Triggers.$Parameter | sort -Unique } } if ($Value.GetType().FullName -eq "System.String") { if (($target -eq $null) -and ([string]::IsNullOrEmpty($Value))) { return $true Write-Verbose ("{0} : {1} ({2})" -f $Parameter, $result, $target) } } # value check $result = $target -eq $Value Write-Verbose ("{0} : {1} ({2})" -f $Parameter, $result, $target) return $result } function TestScheduledTaskExecutionTimeLimit { [OutputType([bool])] [CmdletBinding()] param ( [parameter(Mandatory = $true)] [Microsoft.Management.Infrastructure.CimInstance]$ScheduledTask, [parameter(Mandatory = $false)] [TimeSpan]$Value ) $private:parameter = "ExecutionTimeLimit" # skip null if ($Value -eq $null) { Write-Debug ("Skipping {0} as passed value is null" -f $Parameter) return $true } Write-Debug ("Checking {0} is match with : {1}min" -f $parameter, $Value.TotalMinutes) $executionTimeLimitTimeSpan = [System.Xml.XmlConvert]::ToTimeSpan($ScheduledTask.Settings.$parameter) $result = $Value -eq $executionTimeLimitTimeSpan Write-Verbose ("{0} : {1} ({2}min)" -f $parameter, $result, $executionTimeLimitTimeSpan.TotalMinutes) return $result } function TestScheduledTaskDisable { [OutputType([bool])] [CmdletBinding()] param ( [parameter(Mandatory = $true)] [Microsoft.Management.Infrastructure.CimInstance]$ScheduledTask, [parameter(Mandatory = $false)] [PSObject]$Value, [bool]$IsExist ) # skip when Parameter not use if ($IsExist -eq $false) { Write-Debug ("Skipping {0} as value not passed to function." -f $Parameter) return $true } # convert Enable -> Disable $target = $ScheduledTask.Settings.Enabled -eq $false # value check Write-Debug ("Checking {0} is match with : {1}" -f "Disable", $Value) $result = $target -eq $Value Write-Verbose ("{0} : {1} ({2})" -f "Disable", $result, $target) return $result } function TestScheduledTaskScheduledAt { [OutputType([bool])] [CmdletBinding()] param ( [parameter(Mandatory = $true)] [Microsoft.Management.Infrastructure.CimInstance]$ScheduledTask, [parameter(Mandatory = $false)] [DateTime[]]$Value ) $private:parameter = "StartBoundary" # skip null if ($Value -eq $null) { Write-Debug ("Skipping {0} as passed value is null" -f $Parameter) return $true } $valueCount = ($Value | measure).Count $scheduleCount = ($ScheduledTask.Triggers | measure).Count if ($valueCount -ne $scheduleCount) { throw New-Object System.ArgumentException ("Argument length not match with current ScheduledAt {0} and passed ScheduledAt {1}." -f $scheduleCount, $valueCount) } $result = @() for ($i = 0; $i -le ($ScheduledTask.Triggers.$parameter.Count -1); $i++) { Write-Debug ("Checking {0} is match with : {1}" -f $parameter, $Value[$i]) $startBoundaryDateTime = [System.Xml.XmlConvert]::ToDateTime(@($ScheduledTask.Triggers.$parameter)[$i]) $result += @($Value)[$i] -eq $startBoundaryDateTime Write-Verbose ("{0} : {1} ({2})" -f $parameter, $result[$i], $startBoundaryDateTime) } return $result | sort -Unique } function TestScheduledTaskScheduledRepetition { [OutputType([bool])] [CmdletBinding()] param ( [parameter(Mandatory = $true)] [Microsoft.Management.Infrastructure.CimInstance]$ScheduledTask, [parameter(Mandatory = $true)] [string]$Parameter, [parameter(Mandatory = $false)] [TimeSpan[]]$Value ) # skip null if ($Value -eq $null) { Write-Debug ("Skipping {0} as passed value is null" -f $Parameter) return $true } $valueCount = ($Value | measure).Count $scheduleCount = ($ScheduledTask.Triggers | measure).Count if ($valueCount -ne $scheduleCount) { throw New-Object System.ArgumentException ("Arugument length not match with current ScheduledAt {0} and passed ScheduledAt {1}." -f $scheduleCount, $valueCount) } $result = @() for ($i = 0; $i -le ($ScheduledTask.Triggers.Repetition.$Parameter.Count -1); $i++) { Write-Debug ("Checking {0} is match with : {1}" -f $Parameter, $Value[$i]) $target = [System.Xml.XmlConvert]::ToTimeSpan(@($ScheduledTask.Triggers.Repetition.$Parameter)[$i]) $result = @($Value)[$i] -eq $target Write-Verbose ("{0} : {1} ({2})" -f $Parameter, $result[$i], $target.TotalMinutes) } return $result | sort -Unique } function TestScheduledTaskTriggerBy { [OutputType([bool])] [CmdletBinding()] param ( [parameter(Mandatory = $true)] [System.Xml.XmlDocument]$ScheduledTaskXml, [parameter(Mandatory = $true)] [string]$Parameter, [parameter(Mandatory = $false)] [PSObject]$Value, [bool]$IsExist ) # skip when Parameter not use if ($IsExist -eq $false) { Write-Debug ("Skipping {0} as value not passed to function." -f $Parameter) return $true } $trigger = ($ScheduledTaskXml.task.Triggers.CalendarTrigger.ScheduleByDay | measure).Count $result = $false switch ($Parameter) { "Daily" { Write-Debug "Checking Trigger is : Daily" $result = if ($Value) { $trigger -ne 0 } else { $trigger-eq 0 } Write-Verbose ("{0} : {1} ({2})" -f $Parameter, $result, $trigger) } "Once" { Write-Debug "Checking Trigger is : Once" $result = if ($Value) { $trigger -eq 0 } else { $trigger -ne 0 } Write-Verbose ("{0} : {1} ({2})" -f $Parameter, $result, $trigger) } } return $result } } end { #region Root $private:result = $true # get whole task $root = Get-ScheduledTask # TaskPath $taskResult = GetScheduledTask -ScheduledTask $root -Parameter TaskPath -Value $TaskPath if ($taskResult.result -eq $false){ return $taskResult.Result; } # TaskName $taskResult = GetScheduledTask -ScheduledTask $taskResult.task -Parameter Taskname -Value $TaskName if ($taskResult.result -eq $false){ return $taskResult.Result; } # default $current = $taskResult.task if (($current | measure).Count -eq 0){ return $false } # export as xml [xml]$script:xml = Export-ScheduledTask -TaskName $current.TaskName -TaskPath $current.TaskPath # Description $result = TestScheduledTask -ScheduledTask $current -Parameter Description -Value $Description -Type ([ValentiaScheduledParameterType]::Root) -IsExist ($PSBoundParameters.ContainsKey('Description')) if ($result -eq $false){ return $result; } #endregion #region Action # Execute $result = TestScheduledTask -ScheduledTask $current -Parameter Execute -Value $Execute -Type ([ValentiaScheduledParameterType]::Actions) -IsExist ($PSBoundParameters.ContainsKey('Execute')) if ($result -eq $false){ return $result; } # Arguments $result = TestScheduledTask -ScheduledTask $current -Parameter Arguments -Value $Argument -Type ([ValentiaScheduledParameterType]::Actions) -IsExist ($PSBoundParameters.ContainsKey('Argument')) if ($result -eq $false){ return $result; } # WorkingDirectory $result = TestScheduledTask -ScheduledTask $current -Parameter WorkingDirectory -Value $WorkingDirectory -Type ([ValentiaScheduledParameterType]::Actions) -IsExist ($PSBoundParameters.ContainsKey('WorkingDirectory')) if ($result -eq $false){ return $result; } #endregion #region Principal # UserId $result = TestScheduledTask -ScheduledTask $current -Parameter UserId -Value $Credential.UserName -Type ([ValentiaScheduledParameterType]::Principal) -IsExist ($PSBoundParameters.ContainsKey('Credential')) if ($result -eq $false){ return $result; } # RunLevel $result = TestScheduledTask -ScheduledTask $current -Parameter RunLevel -Value $Runlevel -Type ([ValentiaScheduledParameterType]::Principal) -IsExist ($PSBoundParameters.ContainsKey('Runlevel')) if ($result -eq $false){ return $result; } #endregion #region Settings # Compatibility $result = TestScheduledTask -ScheduledTask $current -Parameter Compatibility -Value $Compatibility -Type ([ValentiaScheduledParameterType]::Settings) -IsExist ($PSBoundParameters.ContainsKey('Compatibility')) if ($result -eq $false){ return $result; } # ExecutionTimeLimit $result = TestScheduledTaskExecutionTimeLimit -ScheduledTask $current -Value $ExecutionTimeLimit if ($result -eq $false){ return $result; } # Hidden $result = TestScheduledTask -ScheduledTask $current -Parameter Hidden -Value $Hidden -Type ([ValentiaScheduledParameterType]::Settings) -IsExist ($PSBoundParameters.ContainsKey('Hidden')) if ($result -eq $false){ return $result; } # Disable $result = TestScheduledTaskDisable -ScheduledTask $current -Value $Disable -IsExist ($PSBoundParameters.ContainsKey('Disable')) if ($result -eq $false){ return $result; } #endregion #region Triggers # SchduledAt $result = TestScheduledTaskScheduledAt -ScheduledTask $current -Value $ScheduledAt if ($result -contains $false){ return $false; } # ScheduledTimeSpan (Repetition Interval) $result = TestScheduledTaskScheduledRepetition -ScheduledTask $current -Value $ScheduledTimeSpan -Parameter Interval if ($result -contains $false){ return $false; } # ScheduledDuration (Repetition Duration) $result = TestScheduledTaskScheduledRepetition -ScheduledTask $current -Value $ScheduledDuration -Parameter Duration if ($result -contains $false){ return $false; } # Daily $result = TestScheduledTaskTriggerBy -ScheduledTaskXml $xml -Parameter Daily -Value $Daily -IsExist ($PSBoundParameters.ContainsKey('Daily')) if ($result -eq $false){ return $result; } # Once $result = TestScheduledTaskTriggerBy -ScheduledTaskXml $xml -Parameter Once -Value $Once -IsExist ($PSBoundParameters.ContainsKey('Once')) if ($result -eq $false){ return $result; } #endregion return $result } } # file loaded from path : \functions\Helper\ScheduledTask\Test-ValentiaScheduledTask.ps1 #Requires -Version 3.0 #-- Deploy Folder/File Module Functions --# <# .SYNOPSIS PowerShell Sed alternate function .DESCRIPTION This cmdlet replace string in the file as like as sed on linux .NOTES Author: guitarrapc Created: 04/Oct/2013 .EXAMPLE Invoke-ValentiaSed -path D:\Deploygroup\*.ps1 -searchPattern "^10.0.0.10$" -replaceWith "#10.0.0.10" -overwrite -------------------------------------------- replace regex ^10.0.0.10$ with # 10.0.0.10 and replace file. (like sed -f "s/^10.0.0.10$/#10.0.0.10" -i) .EXAMPLE Invoke-ValentiaSed -path D:\Deploygroup\*.ps1 -searchPattern "^#10.0.0.10$" -replaceWith "10.0.0.10" -------------------------------------------- replace regex ^10.0.0.10$ with # 10.0.0.10 and not replace file. #> function Invoke-ValentiaSed { [CmdletBinding()] param ( [parameter(position = 0, mandatory = $true, ValueFromPipeline = 1, ValueFromPipelineByPropertyName = 1)] [string]$path, [parameter(position = 1, mandatory = $true, ValueFromPipeline = 1,ValueFromPipelineByPropertyName = 1)] [string]$searchPattern, [parameter(position = 2, mandatory = $true,ValueFromPipeline = 1, ValueFromPipelineByPropertyName = 1)] [string]$replaceWith, [parameter(position = 3, mandatory = $false)] [Microsoft.PowerShell.Commands.FileSystemCmdletProviderEncoding]$encoding = $valentia.fileEncode, [parameter(position = 4, mandatory = $false)] [switch]$overWrite, [parameter(position = 5, mandatory = $false)] [switch]$compress ) $read = Select-String -Path $path -Pattern $searchPattern -Encoding $encoding $read.path ` | sort -Unique ` | %{Write-Warning ("Executing string replace for '{0}'. 'overwrite': '{1}'." -f $path, ($PSBoundParameters.overWrite.IsPresent -eq $true)) $path = $_ $extention = [System.IO.Path]::GetExtension($path) if ($overWrite) { $tmpextension = "$extention" + "______" $tmppath = [System.IO.Path]::ChangeExtension($path,$tmpextension) ("execute replace string '{0}' with '{1}' for file '{2}', Output to '{3}'" -f $searchPattern, $replaceWith, $path, $tmppath) | Write-ValentiaVerboseDebug Get-Content -Path $path ` | %{$_ -replace $searchPattern,$replaceWith} ` | Out-File -FilePath $tmppath -Encoding $valentia.fileEncode -Force -Append ("remove original file '{0}'" -f $path, $tmppath) | Write-ValentiaVerboseDebug Remove-Item -Path $path -Force ("rename tmp file '{0}' to original file '{1}'" -f $tmppath, $path) | Write-ValentiaVerboseDebug Rename-Item -Path $tmppath -NewName ([System.IO.Path]::ChangeExtension($tmppath,$extention)) } else { ("execute replace string '{0}' with '{1}' for file '{2}'" -f $searchPattern, $replaceWith, $path) | Write-ValentiaVerboseDebug if (-not $PSBoundParameters.Compress.IsPresent) { Get-Content -Path $path -Encoding $encoding ` | %{$_ -replace $searchPattern,$replaceWith} } } } } # file loaded from path : \functions\Helper\Sed\Invoke-ValentiaSed.ps1 #Requires -Version 3.0 #-- SymbolicLink Functions --# <# .SYNOPSIS This function will detect only SymbolicLink items. .DESCRIPTION PowerShell SymbolicLink function. Alternative to mklink Symbolic Link. This function detect where input file fullpath item is file/directory SymbolicLink, then only Ennumerate if it is SymbolicLink. .NOTES Author: guitarrapc Created: 12/Aug/2014 .EXAMPLE ls d:\ | Get-ValentiaSymbolicLink -------------------------------------------- Pipeline Input to detect SymbolicLink items. .EXAMPLE Get-ValentiaSymbolicLink (ls d:\).FullName -------------------------------------------- Parameter Input to detect SymbolicLink items. #> function Get-ValentiaSymbolicLink { [OutputType([System.IO.DirectoryInfo[]])] [cmdletBinding()] param ( [parameter(mandatory = $true, Position = 0, ValueFromPipeline =1, ValueFromPipelineByPropertyName = 1)] [Alias('FullName')] [String[]]$Path ) begin { $private:ErrorActionPreference = $valentia.preference.ErrorActionPreference.custom function IsFile ([string]$Path) { if ([System.IO.File]::Exists($Path)) { Write-Verbose ("Input object : '{0}' detected as File." -f $Path) return [System.IO.FileInfo]($Path) } } function IsDirectory ([string]$Path) { if ([System.IO.Directory]::Exists($Path)) { Write-Verbose ("Input object : '{0}' detected as Directory." -f $Path) return [System.IO.DirectoryInfo] ($Path) } } function IsFileReparsePoint ([System.IO.FileInfo]$Path) { Write-Verbose ('File attribute detected as ReparsePoint') $fileAttributes = [System.IO.FileAttributes]::Archive, [System.IO.FileAttributes]::ReparsePoint -join ', ' $attribute = [System.IO.File]::GetAttributes($Path) $result = $attribute -eq $fileAttributes if ($result) { Write-Verbose ('Attribute detected as ReparsePoint. : {0}' -f $attribute) return $result } else { Write-Verbose ('Attribute detected as NOT ReparsePoint. : {0}' -f $attribute) return $result } } function IsDirectoryReparsePoint ([System.IO.DirectoryInfo]$Path) { $directoryAttributes = [System.IO.FileAttributes]::Directory, [System.IO.FileAttributes]::ReparsePoint -join ', ' $result = $Path.Attributes -eq $directoryAttributes if ($result) { Write-Verbose ('Attribute detected as ReparsePoint. : {0}' -f $Path.Attributes) return $result } else { Write-Verbose ('Attribute detected as NOT ReparsePoint. : {0}' -f $Path.Attributes) return $result } } } process { try { $Path ` | %{ if ($file = IsFile -Path $_) { if (IsFileReparsePoint -Path $file.FullName) { # [Valentia.SymbolicLinkGet]::GetSymbolicLinkTarget() # [System.Type]::GetType($typeQualifiedName)::GetSymbolicLinkTarget() $symTarget = [Valentia.CS.SymbolicLink]::GetSymbolicLinkTarget($file.FullName) Add-Member -InputObject $file -MemberType NoteProperty -Name SymbolicPath -Value $symTarget -Force return $file } } elseif ($directory = IsDirectory -Path $_) { if (IsDirectoryReparsePoint -Path $directory.FullName) { # [Valentia.SymbolicLinkGet]::GetSymbolicLinkTarget() # [System.Type]::GetType($typeQualifiedName)::GetSymbolicLinkTarget() $symTarget = [Valentia.CS.SymbolicLink]::GetSymbolicLinkTarget($directory.FullName) Add-Member -InputObject $directory -MemberType NoteProperty -Name SymbolicPath -Value $symTarget -Force return $directory } } } } catch { throw $_ } } } # file loaded from path : \functions\Helper\SymbolicLink\Get-ValentiaSymbolicLink.ps1 #Requires -Version 3.0 #-- SymbolicLink Functions --# <# .SYNOPSIS This function will Remove only SymbolicLink items. .DESCRIPTION PowerShell SymbolicLink function. Alternative to mklink Symbolic Link. This function detect where input file fullpath item is file/directory SymbolicLink, then only remove if it is SymbolicLink. You don't need to care about input Path is FileInfo or DirectoryInfo. .NOTES Author: guitarrapc Created: 12/Aug/2014 .EXAMPLE ls d:\ | Remove-ValentiaSymbolicLink -------------------------------------------- Pipeline Input to detect SymbolicLink items. .EXAMPLE Remove-ValentiaSymbolicLink (ls d:\).FullName -------------------------------------------- Parameter Input to detect SymbolicLink items. #> function Remove-ValentiaSymbolicLink { [OutputType([Void])] [cmdletBinding()] param ( [parameter(mandatory = $true, Position = 0, ValueFromPipeline =1, ValueFromPipelineByPropertyName = 1)] [Alias('FullName')] [String[]]$Path ) begin { $script:ErrorActionPreference = $valentia.preference.ErrorActionPreference.custom function IsFile ([string]$Path) { if ([System.IO.File]::Exists($Path)) { Write-Verbose ("Input object : '{0}' detected as File." -f $Path) return [System.IO.FileInfo]($Path) } } function IsDirectory ([string]$Path) { if ([System.IO.Directory]::Exists($Path)) { Write-Verbose ("Input object : '{0}' detected as Directory." -f $Path) return [System.IO.DirectoryInfo] ($Path) } } function IsFileReparsePoint ([System.IO.FileInfo]$Path) { Write-Verbose ('File attribute detected as ReparsePoint') $fileAttributes = [System.IO.FileAttributes]::Archive, [System.IO.FileAttributes]::ReparsePoint -join ', ' $attribute = [System.IO.File]::GetAttributes($Path.fullname) $result = $attribute -eq $fileAttributes if ($result) { Write-Verbose ('Attribute detected as ReparsePoint. : {0}' -f $attribute) return $result } else { Write-Verbose ('Attribute detected as NOT ReparsePoint. : {0}' -f $attribute) return $result } } function IsDirectoryReparsePoint ([System.IO.DirectoryInfo]$Path) { $directoryAttributes = [System.IO.FileAttributes]::Directory, [System.IO.FileAttributes]::ReparsePoint -join ', ' $result = $Path.Attributes -eq $directoryAttributes if ($result) { Write-Verbose ('Attribute detected as ReparsePoint. : {0}' -f $Path.Attributes) return $result } else { Write-Verbose ('Attribute detected as NOT ReparsePoint. : {0}' -f $Path.Attributes) return $result } } function RemoveFileReparsePoint ([System.IO.FileInfo]$Path) { [System.IO.File]::Delete($Path.FullName) } function RemoveDirectoryReparsePoint ([System.IO.DirectoryInfo]$Path) { [System.IO.Directory]::Delete($Path.FullName) } } process { try { $Path ` | %{ if ($file = IsFile -Path $_) { if (IsFileReparsePoint -Path $file) { RemoveFileReparsePoint -Path $file } } elseif ($directory = IsDirectory -Path $_) { if (IsDirectoryReparsePoint -Path $directory) { RemoveDirectoryReparsePoint -Path $directory } } } } catch { throw $_ } } } # file loaded from path : \functions\Helper\SymbolicLink\Remove-ValentiaSymbolicLink.ps1 #Requires -Version 3.0 <# .SYNOPSIS This function will Set SymbolicLink items for desired Path. .DESCRIPTION PowerShell SymbolicLink function. Alternative to mklink Symbolic Link. This function will create Symbolic Link for input file fullpath. Also it works as like LINQ Zip method for different number items was passed for each -Path and -SymbolicPath. As Zip use minimal number item, this function also follow it. .NOTES Author: guitarrapc Created: 12/Aug/2014 .EXAMPLE ls d:\ ` | select -Last 2 ` | %{ @{ Path = $_.FullName SymbolicPath = Join-Path "d:\zzzzz" $_.Name } } ` | Set-SymbolicLink -Verbose-------------------------------------------- Pipeline Input to create SymbolicLink items. This will make symbolic in d:\zzzz with samename of input Path name. This means you can easily create Symbolic for different Path. .EXAMPLE Set-SymbolicLink -Path (ls d:\ | select -Last 2).FullName -SymbolicPath d:\hoge1, d:\hoge2, d:\hoge3 -Verbose -------------------------------------------- Parameter Input. This will create Symbolic Link for -Path input 2 items, with -SymbolicPath input d:\hoge1 and d:\hoge2. As number input was less with -Path, d:\hoge3 will be ignore. #> function Set-ValentiaSymbolicLink { [OutputType([Void])] [cmdletBinding(DefaultParameterSetName = "ForceFile")] param ( [parameter(mandatory = $true, Position = 0, ValueFromPipeline =1, ValueFromPipelineByPropertyName = 1)] [Alias('TargetPath')] [Alias('FullName')] [String[]]$Path, [parameter(mandatory = $true, Position = 1, ValueFromPipelineByPropertyName = 1)] [String[]]$SymbolicPath, [parameter(mandatory = $false, Position = 2, ValueFromPipelineByPropertyName = 1, ParameterSetName = "ForceFile")] [bool]$ForceFile = $false, [parameter(mandatory = $false, Position = 2, ValueFromPipelineByPropertyName = 1, ParameterSetName = "ForceDirectory")] [bool]$ForceDirectory = $false ) begin { $private:ErrorActionPreference = $valentia.preference.ErrorActionPreference.custom $prefix = "_" $i = 0 # Initialize prefix Length function IsFile ([string]$Path) { if ([System.IO.File]::Exists($Path)) { Write-Verbose ("Input object : '{0}' detected as File." -f $Path) return [System.IO.FileInfo]($Path) } } function IsDirectory ([string]$Path) { if ([System.IO.Directory]::Exists($Path)) { Write-Verbose ("Input object : '{0}' detected as Directory." -f $Path) return [System.IO.DirectoryInfo] ($Path) } } function IsFileAttribute ([System.IO.FileInfo]$Path) { $fileAttributes = [System.IO.FileAttributes]::Archive $attribute = [System.IO.File]::GetAttributes($Path.fullname) $result = $attribute -eq $fileAttributes if ($result) { Write-Verbose ('Attribute detected as File Archive. : {0}' -f $attribute) return $result } else { Write-Verbose ('Attribute detected as NOT File archive. : {0}' -f $attribute) return $result } } function IsDirectoryAttribute ([System.IO.DirectoryInfo]$Path) { $directoryAttributes = [System.IO.FileAttributes]::Directory $result = $Path.Attributes -eq $directoryAttributes if ($result) { Write-Verbose ('Attribute detected as Directory. : {0}' -f $Path.Attributes) return $result } else { Write-Verbose ('Attribute detected as NOT Directory. : {0}' -f $Path.Attributes) return $result } } } process { # Work as like LINQ Zip() method $zip = New-ValentiaZipPairs -first $Path -second $SymbolicPath foreach ($x in $zip) { # reverse original key $targetPath = $x.item1 $SymbolicNewPath = $x.item2 if ($ForceFile -eq $true) { [Valentia.CS.SymbolicLink]::CreateSymLink($SymbolicNewPath, $Path, $false) } elseif ($ForceDirectory -eq $true) { [Valentia.CS.SymbolicLink]::CreateSymLink($SymbolicNewPath, $Path, $true) } elseif ($file = IsFile -Path $targetPath) { # Check File Type if (IsFileAttribute -Path $file) { Write-Verbose ("symbolicPath : '{0}', target : '{1}', isDirectory : '{2}'" -f $SymbolicNewPath, $file.fullname, $false) [Valentia.CS.SymbolicLink]::CreateSymLink($SymbolicNewPath, $file.fullname, $false) } } elseif ($directory = IsDirectory -Path $targetPath) { # Check Directory Type if (IsDirectoryAttribute -Path $directory) { Write-Verbose ("symbolicPath : '{0}', target : '{1}', isDirectory : '{2}'" -f $SymbolicNewPath, $directory.fullname, $true) [Valentia.CS.SymbolicLink]::CreateSymLink($SymbolicNewPath, $directory.fullname, $true) } } } } } # file loaded from path : \functions\Helper\SymbolicLink\Set-ValentiaSymbolicLink.ps1 #Requires -Version 3.0 #-- SymbolicLink Functions --# <# .SYNOPSIS This function will Test whether target path is Symbolic Link or not. .DESCRIPTION If target is Symbolic Link (reparse point), function will return $true. Others, return $false. .NOTES Author: guitarrapc Created: 12/Feb/2015 .EXAMPLE Test-ValentiaSymbolicLink -Path "d:\SymbolicLink" -------------------------------------------- As Path is Symbolic Link, this returns $true. #> function Test-ValentiaSymbolicLink { [OutputType([System.IO.DirectoryInfo[]])] [cmdletBinding()] param ( [parameter(mandatory = $true, Position = 0, ValueFromPipeline =1, ValueFromPipelineByPropertyName = 1)] [Alias('FullName')] [String]$Path ) begin { $script:ErrorActionPreference = $valentia.preference.ErrorActionPreference.custom } process { $result = Get-ValentiaSymbolicLink -Path $Path if ($null -eq $result) { return $false } return $true } } # file loaded from path : \functions\Helper\SymbolicLink\Test-ValentiaSymbolicLink.ps1 #Requires -Version 3.0 #-- Helper Function --# <# .SYNOPSIS Convert PowerShell script to Valentia Task format .DESCRIPTION You can specify "filepath for PowerShell Script" or "scriptBlock". This Cmldet will automatically add "task $taskname -Action {" on top and "}" on bottom. .NOTES Author: guitarrapc Created: 18/Nov/2013 .EXAMPLE ConvertTo-ValentiaTask -inputFilePath d:\hogehoge.ps1 -taskName hoge -outputFilePath d:\fuga.ps1 -------------------------------------------- Convert PowerShell Script written in inputFilePath into valentia Task file. .EXAMPLE ConvertTo-ValentiaTask -scriptBlock {ps} -taskName test -outputFilePath d:\test.ps1 -------------------------------------------- Convert ScriptBlock into valentia Task file. #> function ConvertTo-ValentiaTask { [CmdletBinding(DefaultParameterSetName = "File")] param ( # Path to PowerShell Script .ps1 you want to convert into Task [Parameter(Position = 0, mandatory = $true, ParameterSetName = "File")] [string]$inputFilePath, # Path to PowerShell Script .ps1 you want to convert into Task [Parameter(Position = 1, mandatory = $false, ParameterSetName = "File")] [Microsoft.PowerShell.Commands.FileSystemCmdletProviderEncoding]$encoding = $valentia.fileEncode, # Script Block to Convert into Task [Parameter(Position = 0, mandatory = $true, ParameterSetName = "Script")] [scriptBlock]$scriptBlock, # Task Name you want to set [Parameter(Position = 1, mandatory = $true)] [string]$taskName, # Path to output Task [Parameter(Position = 2, mandatory = $true)] [string]$outputFilePath ) begin { $ErrorActionPreference = $valentia.preference.ErrorActionPreference.custom if ($PSBoundParameters.inputFilePath) { if (Test-Path $inputFilePath) { $read = Get-Content -Path $inputFilePath -Encoding $encoding -Raw } else { throw ("Path not found exception. file path '{0}' not exists." -f $inputFilePath) } } elseif ($PSBoundParameters.scriptBlock) { $read = $scriptBlock } } process { try { # create String Builder $sb = New-Object System.Text.StringBuilder # append Header $sb.AppendLine($("Task {0} -Action {1}" -f $taskName,"{")) > $null # append Original source $sb.AppendLine($read) > $null # append end charactor $sb.AppendLine("}") > $null # serialize $output = $sb.ToString() } finally { $sb.Clear() > $null } } end { $output | Out-File -FilePath $outputFilePath -Encoding $valentia.fileEncode } } # file loaded from path : \functions\Helper\Task\ConvertTo-ValentiaTask.ps1 #Requires -Version 3.0 #-- Public Module Functions to load Task --# # Task <# .SYNOPSIS Load Task File format into $valentia.context.tasks.$taskname hashtable. .DESCRIPTION Loading ps1 file which format is task <taskname> -Action { <scriptblock> } .NOTES Author: guitarrapc Created: 20/June/2013 .EXAMPLE task taskname -Action { What you want to do in ScriptBlock} -------------------------------------------- This is format sample. .EXAMPLE task lstest -Action { Get-ChildItem c:\ } -------------------------------------------- Above example will create taskkey as lstest, run "Get-ChildItem c:\" when invoke. #> function Get-ValentiaTask { [CmdletBinding()] param ( [Parameter(Position = 0, mandatory = $true, HelpMessage = "Input TaskName you want to set and not dupricated.")] [string]$Name = $null, [Parameter(Position = 1, mandatory = $false, HelpMessage = "Write ScriptBlock Action to execute with this task.")] [scriptblock]$Action = $null ) # Load Task Write-Verbose $valeWarningMessages.warn_import_task_begin $newTask = @{ Name = $Name Action = $Action } # convert into LowerCase for keyname Write-Verbose $valeWarningMessages.warn_import_task_end $taskKey = $Name.ToLower() # Get current context variables Write-Verbose $valeWarningMessages.warn_get_current_context $currentContext = $valentia.context.Peek() # Check dupricate key name if ($currentContext.tasks.ContainsKey($taskKey)) { throw $valeErrorMessages.error_duplicate_task_name -F $Name } else { $valeWarningMessages.warn_set_taskkey | Write-ValentiaVerboseDebug $currentContext.tasks.$taskKey = $newTask } # return taskkey to determin key name in $valentia.context.tasks.$taskkey return $taskKey } # file loaded from path : \functions\Helper\Task\Get-ValentiaTask.ps1 #Requires -Version 3.0 #-- Prerequisite OS Setting Module Functions --# <# .SYNOPSIS Create New Local User for Deployment .DESCRIPTION Deployment will use deploy user account credential to avoid any change for administartor. You must add all this user credential for each clients. # User Flag Property Samples. You should combinate these 0x00zz if required. # # &H0001 Run LogOn Script # 0X0001 ADS_UF_SCRIPT # # &H0002 Account Disable # 0X0002 ADS_UF_ACCOUNTDISABLE # # &H0008 Account requires Home Directory # 0X0008 ADS_UF_HOMEDIR_REQUIRED # # &H0010 Account Lockout # 0X0010 ADS_UF_LOCKOUT # # &H0020 No Password reqyured for account # 0X0020 ADS_UF_PASSWD_NOTREQD # # &H0040 No change Password # 0X0040 ADS_UF_PASSWD_CANT_CHANGE # # &H0080 Allow Encypted Text Password # 0X0080 ADS_UF_ENCRYPTED_TEXT_PASSWORD_ALLOWED # # 0X0100 ADS_UF_TEMP_DUPLICATE_ACCOUNT # 0X0200 ADS_UF_NORMAL_ACCOUNT # 0X0800 ADS_UF_INTERDOMAIN_TRUST_ACCOUNT # 0X1000 ADS_UF_WORKSTATION_TRUST_ACCOUNT # 0X2000 ADS_UF_SERVER_TRUST_ACCOUNT # # &H10000 Password infinit # 0X10000 ADS_UF_DONT_EXPIRE_PASSWD # # 0X20000 ADS_UF_MNS_LOGON_ACCOUNT # # &H40000 Smart Card Required # 0X40000 ADS_UF_SMARTCARD_REQUIRED # # 0X80000 ADS_UF_TRUSTED_FOR_DELEGATION # 0X100000 ADS_UF_NOT_DELEGATED # 0x200000 ADS_UF_USE_DES_KEY_ONLY # # 0x400000 ADS_UF_DONT_REQUIRE_PREAUTH # # &H800000 Password expired # 0x800000 ADS_UF_PASSWORD_EXPIRED # # 0x1000000 ADS_UF_TRUSTED_TO_AUTHENTICATE_FOR_DELEGATION .NOTES Author: guitarrapc Created: 18/Jul/2013 .EXAMPLE New-valentiaOSUser -------------------------------------------- Recommend - Secure Input. secure prompt will up and mask your PASSWORD input as *****. .EXAMPLE New-valentiaOSUser -Password "1231231qawerqwe87$%" -------------------------------------------- NOT-Recommend - Unsecure Input Visible prompt will up and non-mask your PASSWORD input as *****. #> function New-ValentiaOSUser { [CmdletBinding()] param ( [parameter(position = 0, mandatory = $false, HelpMessage = "PSCredential for New OS User setup.")] [PSCredential]$credential = (Get-Credential -Credential $valentia.users.deployUser), [parameter(position = 1, mandatory = $false, HelpMessage = "User account belonging UserGroup.")] [string]$Group = $valentia.group.Name, [parameter(position = 2, mandatory = $false, HelpMessage = "User flag bit to set.")] [string]$UserFlag = $valentia.group.userFlag ) process { if ($IsUserExist) { Set-UserPassword @paramUser } else { New-User @paramUser } $Domain= Get-DomainName $paramUserFlag = @{ targetUser = New-Object System.DirectoryServices.DirectoryEntry(("WinNT://{0}/{1}/{2}" -f $Domain, $HostPC, $user)) UserFlag = $UserFlag } Set-UserFlag @paramUserFlag if ((Get-UserAndGroup @paramUserAndGroup).Groups -ne $Group) { Add-UserToUserGroup @paramGroup } } end { Get-UserAndGroup @paramUserAndGroup } begin { $ErrorActionPreference = $valentia.preference.ErrorActionPreference.custom Set-StrictMode -Version latest $HostPC = [System.Environment]::MachineName $user = $credential.UserName $DirectoryComputer = New-Object System.DirectoryServices.DirectoryEntry(("WinNT://{0},computer" -f $HostPC)) $IsUserExist = Get-CimInstance -ClassName Win32_UserAccount -Filter "LocalAccount='true'" | where Name -eq $user $paramUser = @{ user = $user HostPC = $HostPC Credential = $credential } $paramGroup = @{ Group = $Group HostPC = $HostPC user = $user } $paramUserAndGroup = @{ DirectoryComputer = $DirectoryComputer user = $user } function Get-DomainName { if ((Get-WMIObject Win32_ComputerSystem).PartOfDomain) { $dn = (Get-CimInstance -ClassName win32_computersystem).Domain return (Get-CimInstance -ClassName Win32_NTDomain | where DNSForestName -eq $dn).DomainName } else { return (Get-CimInstance -ClassName win32_computersystem).Domain } } function New-User ($user, $HostPC, $credential) { ("User '{0}' not exist, start creating user." -f $user) | Write-ValentiaVerboseDebug $NewUser = $DirectoryComputer.Create("user", $user) $NewUser.SetPassword(($credential.GetNetworkCredential().password)) $NewUser.SetInfo() } function Set-UserPassword ($user, $HostPC, $credential) { ("User '{0}' already exist, start reset password." -f $user) | Write-ValentiaVerboseDebug $SetUser = New-Object System.DirectoryServices.DirectoryEntry(("WinNT://{0}/{1}" -f $HostPC, $user)) $SetUser.psbase.invoke('SetPassword', $credential.GetNetworkCredential().Password) } function Set-UserFlag ($targetUser, $UserFlag) { "Set userflag to define account as bor '{0}'" -f $UserFlag | Write-ValentiaVerboseDebug $userFlags = $targetUser.Get("UserFlags") $userFlags = $userFlags -bor $UserFlag $targetUser.Put("UserFlags", $userFlags) $targetUser.SetInfo() } function Add-UserToUserGroup ($Group, $HostPC, $user) { ("Assign User to UserGroup '{0}'" -f $Group) | Write-ValentiaVerboseDebug $DirectoryGroup = $DirectoryComputer.GetObject("group", $Group) $DirectoryGroup.Add(("WinNT://{0}/{1}" -f $HostPC, $user)) } function Get-UserAndGroup ($DirectoryComputer, $user) { $DirectoryComputer.Children ` | where SchemaClassName -eq 'user' ` | where Name -eq $user ` | %{ $groups = $_.Groups() | %{$_.GetType().InvokeMember("Name", 'GetProperty', $null, $_, $null)} $_ | %{ [PSCustomObject]@{ UserName = $_.Name Groups = $groups } } } } } } # file loaded from path : \functions\Helper\User\New-ValentiaOSUser.ps1 function New-ValentiaZipPairs { [CmdletBinding()] param ( [parameter(mandatory = $false, Position = 0, ValueFromPipeline = 1, ValueFromPipelineByPropertyName = 1)] [PSObject[]]$first, [parameter(mandatory = $false, Position = 1, ValueFromPipelineByPropertyName = 1)] [PSObject[]]$second, [parameter(mandatory = $false, Position = 2, ValueFromPipelineByPropertyName = 1)] [scriptBlock]$resultSelector ) process { if ([string]::IsNullOrWhiteSpace($first)){ break } if ([string]::IsNullOrWhiteSpace($second)){ break } try { $e1 = @($first).GetEnumerator() while ($e1.MoveNext() -and $e2.MoveNext()) { if ($PSBoundParameters.ContainsKey('resultSelector')) { $first = $e1.Current $second = $e2.Current $context = $resultselector.InvokeWithContext( $null, ($psvariable), { (New-Object System.Management.Automation.PSVariable ("first", $first)), (New-Object System.Management.Automation.PSVariable ("second", $second)) } ) $context } else { $tuple = New-Object 'System.Tuple[PSObject, PSObject]' ($e1.Current, $e2.current) $tuple } } } finally { if(($d1 = $e1 -as [IDisposable]) -ne $null) { $d1.Dispose() } if(($d2 = $e2 -as [IDisposable]) -ne $null) { $d2.Dispose() } if(($d3 = $psvariable -as [IDisposable]) -ne $null) {$d3.Dispose() } if(($d4 = $context -as [IDisposable]) -ne $null) {$d4.Dispose() } if(($d5 = $tuple -as [IDisposable]) -ne $null) {$d5.Dispose() } } } begin { $e2 = @($second).GetEnumerator() $psvariable = New-Object 'System.Collections.Generic.List[System.Management.Automation.psvariable]' } } # file loaded from path : \functions\Helper\Utils\New-ValentiaZpPairs.ps1 #Requires -Version 3.0 #-- Prerequisite OS Setting Module Functions --# <# .SYNOPSIS Get reboot require status for client .DESCRIPTION When Windows Update or Change Hostname event is done, it will requires reboot to take change effect. You can obtain reboot required status with this cmdlet. .NOTES Author: guitarrapc Created: 18/Jul/2013 .EXAMPLE Get-ValentiaRebootRequiredStatus -------------------------------------------- Obtain reboot required status. #> function Get-ValentiaRebootRequiredStatus { [CmdletBinding()] param ( ) begin { $ErrorActionPreference = $valentia.preference.ErrorActionPreference.custom Set-StrictMode -Version latest $WindowsUpdateRebootStatus = $false $FileRenameRebootStatus = $false $WindowsUpdateRebootPath = "HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\WindowsUpdate\Auto Update\RebootRequired" $FileRenameRebootPath = "HKLM:\SYSTEM\CurrentControlSet\Control\Session Manager" } process { if (Test-Path $WindowsUpdateRebootPath) { $WindowsUpdateRebootStatus = $true } if (Get-ItemProperty -Path $FileRenameRebootPath | Get-Member -MemberType NoteProperty | where Name -eq "PendingFileRenameOperations") { $FileRenameRebootStatus = $True } $Result = [PSCustomObject]@{ ComputerName = [Net.DNS]::GetHostName() PendingWindowsUpdateReboot= $WindowsUpdateRebootStatus PendingFileRenameReboot = $FileRenameRebootStatus } } end { return $Result } } # file loaded from path : \functions\Helper\Windows\Get-ValentiaRebootRequiredStatus.ps1 #Requires -Version 3.0 #-- Prerequisite OS Setting Module Functions --# # rename <# .SYNOPSIS Change Computer name as specified usage. .DESCRIPTION To control hosts, set prefix for each client with IPAddress octets. .NOTES Author: guitarrapc Created: 18/Jul/2013 .EXAMPLE Set-valentiaHostName -HostUsage web -------------------------------------------- Change Hostname as web-$PrefixHostName-$PrefixIpString-Ip1-Ip2-Ip3-Ip4 #> function Set-ValentiaHostName { [CmdletBinding()] param ( [Parameter(Position = 0, mandatory = $true, HelpMessage = "set usage for the host.")] [string]$HostUsage, [Parameter(Position = 1, mandatory = $false, HelpMessage = "Set Prefix IpString for hostname if required.")] [string]$PrefixIpString = $valentia.prefic.ipstring, [Parameter(Position = 2, mandatory = $false, HelpMessage = "Set this switch to check whatif.")] [switch]$WhatIf ) begin { $ErrorActionPreference = $valentia.preference.ErrorActionPreference.custom Set-StrictMode -Version latest # Get IpAddress $ipAddress = ([Net.Dns]::GetHostAddresses('').IPAddressToString | Select-String -Pattern "^\d*.\.\d*.\.\d*.\.\d*.").line # Replace . of IpAddress to - $ipAddressString = $ipAddress -replace "\.","-" # Create New Host Name $newHostName = $HostUsage + "-" + $PrefixIpString + $ipAddressString $currentHostName = [Net.Dns]::GetHostName() } process { if ( $currentHostName -eq $newHostName) { Write-Verbose ("Current HostName [ {0} ] was same as new HostName [ {1} ]. Nothing Changed." -f $currentHostName, $newHostName) } else { if ($PSBoundParameters.WhatIf.IsPresent -ne $true) { Write-Warning -Message ("Current HostName [ {0} ] change to New HostName [ {1} ]" -f $currentHostName, $newHostName) Rename-Computer -NewName $newHostName -Force } else { $Host.UI.WriteLine("what if: Current HostName [ {0} ] change to New HostName [ {1} ]" -f $currentHostName, $newHostName) } } } } # file loaded from path : \functions\Helper\Windows\Set-ValentiaHostName.ps1 #Requires -Version 3.0 #-- Helper function --# #-- Check Current PowerShell session is elevated or not --# <# .SYNOPSIS Retrieve elavated status of PowerShell Console. .DESCRIPTION Test-ValentiaPowerShellElevated will check shell was elevated is required for some operations access to system folder, files and objects. .NOTES Author: guitarrapc Date: June 17, 2013 .OUTPUTS bool .EXAMPLE C:\PS> Test-ValentiaPowerShellElevated true .EXAMPLE C:\PS> Test-ValentiaPowerShellElevated false #> function Test-ValentiaPowerShellElevated { [CmdletBinding()] param ( ) $user = [Security.Principal.WindowsIdentity]::GetCurrent() return (New-Object Security.Principal.WindowsPrincipal $user).IsInRole([Security.Principal.WindowsBuiltinRole]::Administrator) } # file loaded from path : \functions\Helper\Windows\Private\Test-ValentiaPowerShellElevated.ps1 #Requires -Version 3.0 #-- Prerequisite OS Setting Module Functions --# <# .SYNOPSIS Enable WsMan Trusted hosts .DESCRIPTION Specify Trustedhosts to allow .NOTES Author: guitarrapc Created: 18/Jul/2013 .EXAMPLE Enable-WsManTrustedHosts -------------------------------------------- allow all hosts as * #> function Enable-ValentiaWsManTrustedHosts { [CmdletBinding()] param ( [Parameter(Position = 0, mandatory = $true, HelpMessage = "Specify TrustedHosts to allow.")] [string]$TrustedHosts, [Parameter(Position = 1, mandatory = $false, HelpMessage = "Specify path to WSMan TrustedHosts.")] [string]$TrustedHostsPath = "WSman:localhost\client\TrustedHosts" ) $ErrorActionPreference = $valentia.preference.ErrorActionPreference.custom Set-StrictMode -Version latest if (-not((Get-ChildItem $TrustedHostsPath).Value -eq $TrustedHosts)) { Set-Item -Path $TrustedHostsPath -Value $TrustedHosts -Force } else { ("WinRM Trustedhosts was alredy enabled for {0}." -f $TrustedHosts) | Write-ValentiaVerboseDebug Get-ChildItem $TrustedHostsPath } } # file loaded from path : \functions\Helper\WsMan\Enable-WsManTrustedHosts.ps1 #Requires -Version 3.0 #-- Prerequisite OS Setting Module Functions --# <# .SYNOPSIS Set WsMan Max Memory Per user to prevent PowerShell failed with large memory usage. .DESCRIPTION This user is allowed a maximum memory. 0 will be unlimited. Default value : 1024 (Windows Server 2012) .NOTES Author: guitarrapc Created: 15/Feb/2014 .EXAMPLE Set-ValentiaWsManMaxMemoryPerShellMB -MaxMemoryPerShellMB 0 -------------------------------------------- set as unlimited #> function Set-ValentiaWsManMaxMemoryPerShellMB { [CmdletBinding()] param ( [Parameter(Position = 0, mandatory = $true, HelpMessage = "Input MaxMemoryPerShellMB. 0 will be unlimited.")] [int]$MaxMemoryPerShellMB, [Parameter(Position = 1, mandatory = $false, HelpMessage = "Set WSMan Path.")] [string]$MaxMemoryPerShellMBPath = "WSMan:\localhost\Shell\MaxMemoryPerShellMB" ) $ErrorActionPreference = $valentia.preference.ErrorActionPreference.custom Set-StrictMode -Version latest if (-not((Get-ChildItem $MaxMemoryPerShellMBPath).Value -eq $MaxMemoryPerShellMB)) { Set-Item -Path $MaxMemoryPerShellMBPath -Value $MaxMemoryPerShellMB -Force -PassThru } else { ("Current value for MaxMemoryPerShellMB is {0}." -f $MaxMemoryPerShellMB) | Write-ValentiaVerboseDebug Get-ChildItem $MaxMemoryPerShellMBPath } } # file loaded from path : \functions\Helper\WsMan\Set-ValentiaWsManMaxMemoryPerShellMB.ps1 #Requires -Version 3.0 #-- Prerequisite OS Setting Module Functions --# <# .SYNOPSIS Set WsMan Max Proccesses Per Shell. .DESCRIPTION Unlimit process. Default value : 100 (Windows Server 2012) .NOTES Author: guitarrapc Created: 15/Feb/2014 .EXAMPLE Set-ValentiaWsManMaxProccessesPerShell -MaxProccessesPerShell 0 -------------------------------------------- set as 100 #> function Set-ValentiaWsManMaxProccessesPerShell { [CmdletBinding()] param ( [Parameter(Position = 0, mandatory = $true, HelpMessage = "Input MaxProccessesPerShell value.")] [int]$MaxProccessesPerShell, [Parameter(Position = 1, mandatory = $false, HelpMessage = "Set path to WSMan MaxProccessesPerShell.")] [string]$MaxProccessesPerShellPath = "WSMan:\localhost\Shell\MaxProcessesPerShell" ) $ErrorActionPreference = $valentia.preference.ErrorActionPreference.custom Set-StrictMode -Version latest if (-not((Get-ChildItem $MaxProccessesPerShellPath).Value -eq $MaxProccessesPerShell)) { Set-Item -Path $MaxProccessesPerShellPath -Value $MaxProccessesPerShell -Force -PassThru } else { ("Current value for MaxShellsPerUser is {0}." -f $MaxProccessesPerShell) | Write-ValentiaVerboseDebug Get-ChildItem $MaxProccessesPerShellPath } } # file loaded from path : \functions\Helper\WsMan\Set-ValentiaWsManMaxProccessesPerShell.ps1 #Requires -Version 3.0 #-- Prerequisite OS Setting Module Functions --# <# .SYNOPSIS Set WsMan Max Shells Per user to prevent "The WS-Management service cannot process the request. .DESCRIPTION This user is allowed a maximum number of xx concurrent shells, which has been exceeded." Default value : 25 (Windows Server 2012) .NOTES Author: guitarrapc Created: 18/Jul/2013 .EXAMPLE Set-ValentiaWsManMaxShellsPerUser -ShellsPerUser 100 -------------------------------------------- set as 100 #> function Set-ValentiaWsManMaxShellsPerUser { [CmdletBinding()] param ( [Parameter(Position = 0, mandatory = $true, HelpMessage = "Input ShellsPerUser count.")] [int]$ShellsPerUser, [Parameter(Position = 1, mandatory = $false, HelpMessage = "Set path to WSMan MaxShellsPerUser.")] [string]$MaxShellsPerUserPath = "WSMan:\localhost\Shell\MaxShellsPerUser" ) $ErrorActionPreference = $valentia.preference.ErrorActionPreference.custom Set-StrictMode -Version latest if (-not((Get-ChildItem $MaxShellsPerUserPath).Value -eq $ShellsPerUser)) { Set-Item -Path $MaxShellsPerUserPath -Value $ShellsPerUser -Force -PassThru } else { ("Current value for MaxShellsPerUser is {0}." -f $ShellsPerUser) | Write-ValentiaVerboseDebug Get-ChildItem $MaxShellsPerUserPath } } # file loaded from path : \functions\Helper\WsMan\Set-ValentiaWsManMaxShellsPerUser.ps1 #Requires -Version 3.0 #-- Public Functions for WSMan Parameter Configuration --# function Set-ValetntiaWSManConfiguration { [CmdletBinding()] param ( [Parameter(Position = 0, mandatory = $false, HelpMessage = "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.'")] [ValidateNotNullOrEmpty()] [int]$ShellsPerUser = $valentia.wsman.MaxShellsPerUser, [Parameter(Position = 1, mandatory = $false, HelpMessage = "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.'")] [ValidateNotNullOrEmpty()] [int]$MaxMemoryPerShellMB = $valentia.wsman.MaxMemoryPerShellMB, [Parameter(Position = 2, mandatory = $false, HelpMessage = "Configure WSMan MaxProccessesPerShell to improve performance")] [ValidateNotNullOrEmpty()] [int]$MaxProccessesPerShell = $valentia.wsman.MaxProccessesPerShell ) $ErrorActionPreference = $valentia.preference.ErrorActionPreference.custom Set-StrictMode -Version latest "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.'" | Write-ValentiaVerboseDebug Set-ValentiaWsManMaxShellsPerUser -ShellsPerUser $ShellsPerUser "Configure WSMan MaxMBPerUser to prevent huge memory consumption crach PowerShell issue." | Write-ValentiaVerboseDebug Set-ValentiaWsManMaxMemoryPerShellMB -MaxMemoryPerShellMB $MaxMemoryPerShellMB "Configure WSMan MaxProccessesPerShell to improve performance" | Write-ValentiaVerboseDebug Set-ValentiaWsManMaxProccessesPerShell -MaxProccessesPerShell $MaxProccessesPerShell "Restart-Service WinRM -PassThru" | Write-ValentiaVerboseDebug Restart-Service WinRM -PassThru } # file loaded from path : \functions\Helper\WsMan\Set-ValetntiaWSManConfiguration.ps1 #Requires -Version 3.0 #-- Public Module Job / Functions for Remote Execution --# # vale <# .SYNOPSIS 1 of invoking valentia by PowerShell Backgroud Job execution to remote host .DESCRIPTION Run Job valentia execution to remote host .NOTES Author: guitarrapc Created: 20/June/2013 .EXAMPLE vale 192.168.1.100 {Get-ChildItem} -------------------------------------------- Get-ChildItem ScriptBlock execute on 192.168.1.100 .EXAMPLE vale 192.168.1.100 {Get-ChildItem; hostname} -------------------------------------------- You can run multiple script in pipeline. .EXAMPLE vale 192.168.1.100 .\default.ps1 -------------------------------------------- You can prepare script file to run, and specify path. .EXAMPLE vale 192.168.1.100,192.168.1.200 .\default.ps1 -------------------------------------------- You can target multiple deploymember with comma separated. Running Synchronously. .EXAMPLE vale DeployGroupFile.ps1 {ScriptBlock} -------------------------------------------- Specify DeployGroupFile and ScriptBlock .EXAMPLE vale DeployGroupFile.ps1 .\default.ps1 -------------------------------------------- You can prepare script file to run, and specify path. #> function Invoke-Valentia { [CmdletBinding(DefaultParameterSetName = "TaskFileName")] param ( [Parameter(Position = 0, mandatory = $true, HelpMessage = "Input target of deploy clients as [DeployGroup filename you sat at deploygroup Folder] or [ipaddress].")] [string[]]$DeployGroups, [Parameter(Position = 1, mandatory = $true, ParameterSetName = "TaskFileName", HelpMessage = "Move to Brach folder you sat taskfile, then input TaskFileName. exclusive with ScriptBlock.")] [ValidateNotNullOrEmpty()] [string]$TaskFileName, [Parameter(Position = 1, mandatory = $true, ParameterSetName = "SctriptBlock", HelpMessage = "Input Script Block {hogehoge} you want to execute with this commandlet. exclusive with TaskFileName")] [ValidateNotNullOrEmpty()] [ScriptBlock]$ScriptBlock, [Parameter(Position = 2, mandatory = $false, HelpMessage = "Usually automatically sat to DeployGroup Folder. No need to modify.")] [ValidateNotNullOrEmpty()] [string]$DeployFolder = (Join-Path $Script:valentia.RootPath ([ValentiaBranchPath]::Deploygroup)), [Parameter(Position = 3, mandatory = $false, HelpMessage = "Input parameter pass into task's arg[0....x].values")] [ValidateNotNullOrEmpty()] [hashtable]$TaskParameter, [Parameter(Position = 4, mandatory = $false, HelpMessage = "Hide execution progress.")] [switch]$Quiet, [Parameter(Position = 5, mandatory = $false, HelpMessage = "Input PSCredential to use for wsman.")] [PSCredential]$Credential = (Get-ValentiaCredential), [Parameter(Position = 6, mandatory = $false, HelpMessage = "Select Authenticateion for Credential.")] [System.Management.Automation.Runspaces.AuthenticationMechanism]$Authentication = $valentia.Authentication, [Parameter(Position = 7, mandatory = $false, HelpMessage = "Select SSL is use or not.")] [switch]$UseSSL = $valentia.UseSSL, [Parameter(Position = 8, mandatory = $false, HelpMessage = "Return success result even if there are error.")] [bool]$SkipException = $false ) process { try { #region Prerequisite # Prerequisite setup $prerequisiteParam = @{ Stopwatch = $TotalstopwatchSession DeployGroups = $DeployGroups TaskFileName = $TaskFileName ScriptBlock = $ScriptBlock DeployFolder = $DeployFolder TaskParameter = $TaskParameter } Set-ValentiaInvokationPrerequisites @prerequisiteParam #endregion #region Process # Job execution $param = @{ Credential = $Credential TaskParameter = $TaskParameter Authentication = $Authentication UseSSL = $UseSSL SkipException = $SkipException ErrorAction = $originalErrorAction } Invoke-ValentiaJobProcess @param #endregion } catch { $valentia.Result.SuccessStatus += $false $valentia.Result.ErrorMessageDetail += $_ if ($ErrorActionPreference -eq 'Stop') { throw $_ } } finally { # obtain Result $resultParam = @{ StopWatch = $TotalstopwatchSession Cmdlet = $($MyInvocation.MyCommand.Name) TaskFileName = $TaskFileName DeployGroups = $DeployGroups SkipException = $SkipException Quiet = $Quiet } Out-ValentiaResult @resultParam # Cleanup valentia Environment Invoke-ValentiaClean } } begin { # Initialize Stopwatch $TotalstopwatchSession = [System.Diagnostics.Stopwatch]::StartNew() # Reset ErrorActionPreference if ($PSBoundParameters.ContainsKey('ErrorAction')) { $originalErrorAction = $ErrorActionPreference } else { $originalErrorAction = $ErrorActionPreference = $valentia.preference.ErrorActionPreference.original } } } # file loaded from path : \functions\Invokation\CommandExecution\Job\Invoke-Valentia.ps1 #Requires -Version 3.0 #-- Private Module Job / Functions for Remote Execution --# <# .SYNOPSIS Invoke Command as Job to remote host .DESCRIPTION Background job execution with Invoke-Command. Allowed to run from C# code. .NOTES Author: guitarrapc Created: 20/June/2013 .EXAMPLE Invoke-ValentiaCommand -ScriptToRun $ScriptToRun .EXAMPLE Invoke-ValentiaCommand -ScriptToRun {ls} .EXAMPLE Invoke-ValentiaCommand -ScriptToRun {ls | where {$_.extensions -eq ".txt"}} .EXAMPLE Invoke-ValentiaCommand {test-connection localhost} #> function Invoke-ValentiaCommand { [CmdletBinding(DefaultParameterSetName = "All")] param ( [Parameter(Position = 0, mandatory = $true, ParameterSetName = "Default", ValueFromPipeline = 1, ValueFromPipelineByPropertyName = 1, HelpMessage = "Input Session")] [string[]]$ComputerNames, [Parameter(Position = 1, mandatory = $true, ParameterSetName = "Default", ValueFromPipeline = 1, ValueFromPipelineByPropertyName = 1, HelpMessage = "Input ScriptBlock. ex) Get-ChildItem, Get-NetAdaptor | where MTUSize -gt 1400")] [ScriptBlock]$ScriptToRun, [Parameter(Position = 2, mandatory = $true, HelpMessage = "Input PSCredential for Remote Command execution.")] [System.Management.Automation.PSCredential]$Credential, [Parameter(Position = 3, mandatory = $false, HelpMessage = "Input parameter pass into task's arg[0....x].")] [hashtable]$TaskParameter, [Parameter(Position = 4, mandatory = $false, HelpMessage = "Input Authentication for credential.")] [System.Management.Automation.Runspaces.AuthenticationMechanism]$Authentication, [Parameter(Position = 5, mandatory = $false, HelpMessage = "Input SSL is use or not.")] [bool]$UseSSL, [Parameter(Position = 6, mandatory = $false, HelpMessage = "Input Skip ErrorActionPreferenceOption.")] [bool]$SkipException ) process { foreach ($computerName in $ComputerNames) { # Run ScriptBlock in Job Write-Verbose ("ScriptBlock..... {0}" -f $($ScriptToRun)) Write-Verbose ("Argumentlist..... {0}" -f $($TaskParameter)) ("Running ScriptBlock to {0} as Job" -f $computerName) | Write-ValentiaVerboseDebug $job = Invoke-Command -ScriptBlock $ScriptToRun -ArgumentList $TaskParameter -ComputerName $computerName -Credential $Credential -Authentication $Authentication -UseSSL:$UseSSL -AsJob $list.Add($job) } # receive job result "Receive all job result." | Write-ValentiaVerboseDebug $jobParam = @{ listJob = $list SkipException = $skipException ErrorAction = $ErrorActionPreference } Receive-ValentiaResult @jobParam } begin { $list = New-Object System.Collections.Generic.List[System.Management.Automation.Job] # Set variable for output each task result $task = @{} # Cleanup previous Job before start if ((Get-Job).count -gt 0) { "Clean up previous Job" | Write-ValentiaVerboseDebug Get-Job | Remove-Job -Force -Verbose:$VerbosePreference } } } # file loaded from path : \functions\Invokation\CommandExecution\Job\Private\Invoke-ValentiaCommand.ps1 #Requires -Version 3.0 #-- Private Module Job / Functions for Remote Execution --# function Invoke-ValentiaJobProcess { [CmdletBinding()] param ( [parameter(mandatory = $false)] [string[]]$ComputerNames = $valentia.Result.DeployMembers, [parameter(mandatory = $false)] [scriptBlock]$ScriptToRun = $valentia.Result.ScriptTorun, [parameter(mandatory = $true)] [PSCredential]$Credential, [parameter(mandatory = $false)] [hashtable]$TaskParameter, [parameter(mandatory = $true)] [System.Management.Automation.Runspaces.AuthenticationMechanism]$Authentication, [parameter(mandatory = $true)] [bool]$UseSSL, [parameter(mandatory = $true)] [bool]$SkipException ) # Splatting $param = @{ ComputerNames = $ComputerNames ScriptToRun = $ScriptToRun Credential = $Credential TaskParameter = $TaskParameter Authentication = $Authentication UseSSL = $UseSSL SkipException = $SkipException ErrorAction = $ErrorActionPreference } # Run ScriptBlock as Sequence for each DeployMember Write-Verbose ("Execute command : {0}" -f $param.ScriptToRun) Write-Verbose ("Target Computers : '{0}'" -f ($param.ComputerNames -join ", ")) # Executing job Invoke-ValentiaCommand @param ` | %{$valentia.Result.Result = New-Object 'System.Collections.Generic.List[PSCustomObject]' }{ $valentia.Result.ErrorMessageDetail += $_.ErrorMessageDetail $valentia.Result.SuccessStatus += $_.SuccessStatus if ($_.host -ne $null) { $hash = [ordered]@{ Hostname = $_.host Values = $_.result Success = $_.success } $valentia.Result.Result.Add([PSCustomObject]$hash) } if(!$quiet) { "Show result for host '{0}'" -f $_.host | Write-ValentiaVerboseDebug $_.result } } } # file loaded from path : \functions\Invokation\CommandExecution\Job\Private\Invoke-ValentiaJobProcess.ps1 #Requires -Version 3.0 #-- Private Module Job / Functions for Remote Execution --# <# .SYNOPSIS Receives a results of one or more jobs. .DESCRIPTION Get background job execution result. .NOTES Author: guitarrapc Created: 14/Feb/2014 .EXAMPLE Receive-ValentiaResult -listJob $listJob #> function Receive-ValentiaResult { [CmdletBinding()] param ( [Parameter(Position = 0, mandatory = $true, ValueFromPipeline = 1, ValueFromPipelineByPropertyName = 1, HelpMessage = "Input list<job> to recieve result of each job.")] [System.Collections.Generic.List[System.Management.Automation.Job]]$listJob, [Parameter(Position = 1, mandatory = $false, HelpMessage = "Input Skip ErrorActionPreferenceOption.")] [bool]$SkipException ) process { # monitor job status "Waiting for job running complete." | Write-ValentiaVerboseDebug Wait-Job -Job $listJob -Force > $null foreach ($job in $listJob) { # Obtain HostName $task.host = $job.Location ("Receive ScriptBlock result from Job for '{0}'" -f $job.Location) | Write-ValentiaVerboseDebug if ($SkipException) { $task.result = Receive-Job -Job $job -ErrorAction SilentlyContinue -ErrorVariable ErrorVariable } else { $task.result = Receive-Job -Job $job -ErrorVariable ErrorVariable } # Error actions if (($ErrorVariable | measure).Count -ne 0) { $task.ErrorMessageDetail = $ErrorVariable $task.SuccessStatus = $false $task.success = $false if (-not $SkipException) { if ($ErrorActionPreference -eq 'Stop') { throw $ErrorVariable } } } else { $task.success = $true } # output $task ("Removing Job ID '{0}'" -f $job.id) | Write-ValentiaVerboseDebug Remove-Job -Job $job -Force } } begin { # Set variable for output $task = @{} } } # file loaded from path : \functions\Invokation\CommandExecution\Job\Private\Receive-ValentiaResult.ps1 #Requires -Version 3.0 #-- Public Module Asynchronous / Functions for Remote Execution --# # valea <# .SYNOPSIS Run Asynchronous valentia execution to remote host .DESCRIPTION Asynchronous running thread through AsyncPipeLine handling PS Runspace. Allowed to run from C# code. .NOTES Author: guitarrapc Created: 20/June/2013 .EXAMPLE valea 192.168.1.100 {Get-ChildItem} -------------------------------------------- Get-ChildItem ScriptBlock execute on 192.168.1.100 .EXAMPLE valea 192.168.1.100 {Get-ChildItem; hostname} -------------------------------------------- You can run multiple script in pipeline. .EXAMPLE valea 192.168.1.100 .\default.ps1 -------------------------------------------- You can prepare script file to run, and specify path. .EXAMPLE valea 192.168.1.100,192.168.1.200 .\default.ps1 -------------------------------------------- You can target multiple deploymember with comma separated. Running Asynchronously. .EXAMPLE valea DeployGroupFile.ps1 {ScriptBlock} -------------------------------------------- Specify DeployGroupFile and ScriptBlock .EXAMPLE valea DeployGroupFile.ps1 .\default.ps1 -------------------------------------------- You can prepare script file to run, and specify path. #> function Invoke-ValentiaAsync { [CmdletBinding(DefaultParameterSetName = "TaskFileName")] param ( [Parameter(Position = 0, mandatory = $true, HelpMessage = "Input target of deploy clients as [DeployGroup filename you sat at deploygroup Folder] or [ipaddress].")] [string[]]$DeployGroups, [Parameter(Position = 1, mandatory = $true, ParameterSetName = "TaskFileName", HelpMessage = "Move to Brach folder you sat taskfile, then input TaskFileName. exclusive with ScriptBlock.")] [ValidateNotNullOrEmpty()] [string]$TaskFileName, [Parameter(Position = 1, mandatory = $true, ParameterSetName = "SctriptBlock", HelpMessage = "Input Script Block {hogehoge} you want to execute with this commandlet. exclusive with TaskFileName")] [ValidateNotNullOrEmpty()] [ScriptBlock]$ScriptBlock, [Parameter(Position = 2, mandatory = $false, HelpMessage = "Usually automatically sat to DeployGroup Folder. No need to modify.")] [ValidateNotNullOrEmpty()] [string]$DeployFolder = (Join-Path $script:valentia.RootPath ([ValentiaBranchPath]::Deploygroup)), [Parameter(Position = 3, mandatory = $false, HelpMessage = "Input parameter pass into task's arg[0....x].Values")] [ValidateNotNullOrEmpty()] [hashtable]$TaskParameter, [Parameter(Position = 4, mandatory = $false, HelpMessage = "Hide execution progress.")] [switch]$Quiet, [Parameter(Position = 5, mandatory = $false, HelpMessage = "Input PSCredential to use for wsman.")] [PSCredential]$Credential = (Get-ValentiaCredential), [Parameter(Position = 6, mandatory = $false, HelpMessage = "Select Authenticateion for Credential.")] [System.Management.Automation.Runspaces.AuthenticationMechanism]$Authentication = $valentia.Authentication, [Parameter(Position = 7, mandatory = $false, HelpMessage = "Select SSL is use or not.")] [switch]$UseSSL = $valentia.UseSSL, [Parameter(Position = 8, mandatory = $false, HelpMessage = "Return success result even if there are error.")] [bool]$SkipException = $false ) process { try { #region Prerequisite # Prerequisite setup $prerequisiteParam = @{ Stopwatch = $TotalstopwatchSession DeployGroups = $DeployGroups TaskFileName = $TaskFileName ScriptBlock = $ScriptBlock DeployFolder = $DeployFolder TaskParameter = $TaskParameter } Set-ValentiaInvokationPrerequisites @prerequisiteParam #endregion #region Process # RunSpace execution $param = @{ Credential = $Credential TaskParameter = $TaskParameter Authentication = $Authentication UseSSL = $UseSSL SkipException = $SkipException ErrorAction = $originalErrorAction quiet = $Quiet } Invoke-ValentiaRunspaceProcess @param #endregion } catch { $valentia.Result.SuccessStatus += $false $valentia.Result.ErrorMessageDetail += $_ if (-not $SkipException) { throw $_ } } finally { # obtain Result $resultParam = @{ StopWatch = $TotalstopwatchSession Cmdlet = $($MyInvocation.MyCommand.Name) TaskFileName = $TaskFileName DeployGroups = $DeployGroups SkipException = $SkipException Quiet = $PSBoundParameters.ContainsKey("quiet") -and $quiet } Out-ValentiaResult @resultParam # Cleanup valentia Environment Invoke-ValentiaClean } } begin { # Initialize Stopwatch $TotalstopwatchSession = [System.Diagnostics.Stopwatch]::StartNew() # Reset ErrorActionPreference if ($PSBoundParameters.ContainsKey('ErrorAction')) { $originalErrorAction = $ErrorActionPreference } else { $originalErrorAction = $ErrorActionPreference = $valentia.preference.ErrorActionPreference.original } } } # file loaded from path : \functions\Invokation\CommandExecution\RunSpacePool\Invoke-ValentiaAsync.ps1 #Requires -Version 3.0 #-- Private Module Function for Async execution --# <# .SYNOPSIS Creating a PowerShell pipeline then executes a ScriptBlock Asynchronous with Remote Host. .DESCRIPTION Pipeline will execute less overhead then Invoke-Command, Job, or PowerShell Cmdlet. All cmdlet will execute with Invoke-Command -ComputerName -Credential wrapped by Invoke-ValentiaAsync pipeline. Wrapped by Pipeline will give you avility to run Invoke-Command Asynchronous. (Usually Sencronous) Asynchrnous execution will complete much faster then Syncronous execution. .NOTES Author: guitarrapc Created: 13/July/2013 .EXAMPLE Invoke-ValeinaAsyncCommand -RunspacePool $(New-ValentiaRunspacePool 10) ` -ScriptBlock { Get-ChildItem } ` -Computers $(Get-Content .\ComputerList.txt) -Credential $(Get-Credential) -------------------------------------------- Above example will concurrently running with 10 processes for each Computers. #> function Invoke-ValentiaAsyncCommand { [Cmdletbinding()] Param ( [Parameter(Position = 0, mandatory = $true, HelpMessage = "Runspace Poll required to set one or more, easy to create by New-ValentiaRunSpacePool.")] [System.Management.Automation.Runspaces.RunspacePool]$RunspacePool, [Parameter(Position = 1, mandatory = $true, HelpMessage = "The scriptblock to be executed to the Remote host.")] [HashTable]$ScriptToRunHash, [Parameter(Position = 2, mandatory = $true, HelpMessage = "Target Computers to be execute.")] [string[]]$DeployMembers, [Parameter(Position = 3, mandatory = $true, HelpMessage = "Remote Login PSCredentail for PS Remoting. (Get-Credential format)")] [HashTable]$CredentialHash, [Parameter(Position = 4, mandatory = $true, HelpMessage = "Input parameter pass into task's arg[0....x].")] [HashTable]$TaskParameterHash, [Parameter(Position = 5, mandatory = $true, HelpMessage = "Input Authentication for credential.")] [HashTable]$AuthenticationHash, [Parameter(Position = 6, mandatory = $true, HelpMessage = "Select SSL is use or not.")] [HashTable]$UseSSLHash ) end { try { # Create PowerShell Instance "Creating PowerShell Instance" | Write-ValentiaVerboseDebug $Pipeline = [System.Management.Automation.PowerShell]::Create() # Add Script and Parameter arguments from Hashtables "Adding Script and Arguments Hastables to PowerShell Instance" | Write-ValentiaVerboseDebug Write-Verbose ('Add InvokeCommand Script : {0}' -f $InvokeCommand) Write-Verbose ("Add ScriptBlock Argument..... Keys : {0}, Values : {1}" -f $($ScriptToRunHash.Keys) , $($ScriptToRunHash.Values)) Write-Verbose ("Add ComputerName Argument..... Keys : {0}, Values : {1}" -f $($ComputerName.Keys) , $($ComputerName.Values)) Write-Verbose ("Add Credential Argument..... Keys : {0}, Values : {1}" -f $($CredentialHash.Keys) , $($CredentialHash.Values)) Write-Verbose ("Add ArgumentList Argument..... Keys : {0}, Values : {1}" -f $($TaskParameterHash.Keys) , $($TaskParameterHash.Values)) Write-Verbose ("Add Authentication Argument..... Keys : {0}, Values : {1}" -f $($AuthenticationHash.Keys), $($AuthenticationHash.Values)) Write-Verbose ("Add UseSSL Argument..... Keys : {0}, Values : {1}" -f $($UseSSLHash.Keys), $($UseSSLHash.Values)) $Pipeline. AddScript($InvokeCommand). AddArgument($ScriptToRunHash). AddArgument($ComputerName). AddArgument($CredentialHash). AddArgument($TaskParameterHash). AddArgument($AuthenticationHash). AddArgument($UseSSLHash) > $null # Add RunSpacePool to PowerShell Instance ("Adding Runspaces {0}" -f $RunspacePool) | Write-ValentiaVerboseDebug $Pipeline.RunspacePool = $RunspacePool # Invoke PowerShell Command "Invoking PowerShell Instance" | Write-ValentiaVerboseDebug $AsyncResult = $Pipeline.BeginInvoke() # Get Result Write-Verbose "Obtain result" $Output = New-Object AsyncPipeline # Output Pipeline Infomation $Output.Pipeline = $Pipeline # Output AsyncCommand Result $Output.AsyncResult = $AsyncResult ("Output Result '{0}' and '{1}'" -f $Output.Pipeline, $Output.AsyncResult) | Write-ValentiaVerboseDebug return $Output } catch { $valentia.Result.SuccessStatus += $false $valentia.Result.ErrorMessageDetail += $_ Write-Error $_ } } begin { # Create Hashtable for ComputerName passed to Pipeline $ComputerName = @{ComputerName = $DeployMember} # Declare execute Comdlet format as Invoke-Command $InvokeCommand = { param( $ScriptToRunHash, $ComputerName, $CredentialHash, $TaskParameterHash, $AuthenticationHash, $UseSSLHash ) $param = @{ ScriptBlock = $($ScriptToRunHash.Values) ComputerName = $($ComputerName.Values) Credential = $($CredentialHash.Values) ArgumentList = $($TaskParameterHash.Values) Authentication = $($AuthenticationHash.Values) UseSSL = $($UseSSLHash.Values) } Invoke-Command @param } } } # file loaded from path : \functions\Invokation\CommandExecution\RunSpacePool\Private\Invoke-ValentiaAsyncCommand.ps1 #Requires -Version 3.0 #-- Private Module Function for Async execution --# function Invoke-ValentiaRunspaceProcess { [CmdletBinding()] param ( [parameter(mandatory = $false)] [string[]]$ComputerNames = $valentia.Result.DeployMembers, [parameter(mandatory = $false)] [scriptBlock]$ScriptToRun = $valentia.Result.ScriptTorun, [parameter(mandatory = $true)] [PSCredential]$Credential, [parameter(mandatory = $false)] [hashtable]$TaskParameter, [parameter(mandatory = $true)] [System.Management.Automation.Runspaces.AuthenticationMechanism]$Authentication, [parameter(mandatory = $true)] [bool]$UseSSL, [parameter(mandatory = $true)] [bool]$SkipException, [parameter(mandatory = $false)] [bool]$quiet ) process { try { # Execute Async Job $asyncPipelineparam = @{ scriptBlock = $scriptBlock Credential = $credential TaskParameter = $TaskParameter Authentication = $Authentication UseSSL = $UseSSL } Invoke-ValentiaAsyncPipeline @asyncPipelineparam # Monitoring status for Async result (Even if no monitoring, but asynchronous result will obtain after all hosts available) Watch-ValentiaAsyncPipelineStatus -AsyncPipelines $valentia.runspace.asyncPipeline # Obtain Async Command Result $asyncResultParam = @{ AsyncPipelines = $valentia.runspace.asyncPipeline quiet = $quiet ErrorAction = $ErrorActionPreference skipException = $skipException } Receive-ValentiaAsyncResults @asyncResultParam ` | %{$valentia.Result.Result = New-Object 'System.Collections.Generic.List[PSCustomObject]' }{ $valentia.Result.ErrorMessageDetail += $_.ErrorMessageDetail $valentia.Result.SuccessStatus += $_.SuccessStatus if ($_.host -ne $null) { $hash = [ordered]@{ Hostname = $_.host Values = $_.result Success = $_.success } $valentia.Result.Result.Add([PSCustomObject]$hash) } if (-not $quiet) { "Show result for host '{0}'" -f $_.host | Write-ValentiaVerboseDebug $_.result } } } finally { # Dispose RunspacePool Remove-ValentiaRunSpacePool # Dispose AsyncPipeline variables $valentia.runspace.asyncPipeline = $null } } } # file loaded from path : \functions\Invokation\CommandExecution\RunSpacePool\Private\Invoke-ValentiaRunspaceProcess.ps1 #Requires -Version 3.0 #-- Private Module Function for Async execution --# <# .SYNOPSIS Receives a results of one or more asynchronous pipelines. .DESCRIPTION This function receives the results of a pipeline running in a separate runspace. Since it is unknown what exists in the results stream of the pipeline, this function will not have a standard return type. .NOTES Author: guitarrapc Created: 13/July/2013 .EXAMPLE $AsyncPipelines += Invoke-ValentiaAsyncCommand -RunspacePool $valentia.runspace.pool.instance -ScriptToRun $ScriptToRun -Deploymember $DeployMember -Credential $credential -Verbose Receive-ValentiaAsyncResults -AsyncPipelines $AsyncPipelines -ShowProgress -------------------------------------------- Above will retrieve Async Result #> function Receive-ValentiaAsyncResults { [Cmdletbinding()] Param ( [Parameter(Position = 0, mandatory = $true, HelpMessage = "An array of Async Pipeline objects, returned by Invoke-ValentiaAsync.")] [System.Collections.Generic.List[AsyncPipeline]]$AsyncPipelines, [Parameter(Position = 1, mandatory = $false, HelpMessage = "Hide execution progress.")] [bool]$quiet, [Parameter(Position = 2, mandatory = $false, HelpMessage = "Input Skip ErrorActionPreferenceOption.")] [bool]$SkipException ) process { foreach($Pipeline in $AsyncPipelines) { try { # Get HostName of Pipeline $task.host = $Pipeline.Pipeline.Commands.Commands.parameters.Value.ComputerName if (-not $quiet) { Write-Warning -Message ("{0} Asynchronous execution done." -f $task.host) } # output Asyanc result $task.result = $Pipeline.Pipeline.EndInvoke($Pipeline.AsyncResult) # Check status of stream if($Pipeline.Pipeline.Streams.Error) { $task.SuccessStatus = $false $task.ErrorMessageDetail = $Pipeline.Pipeline.Streams.Error $task.success = $false if (-not $SkipException) { if ($ErrorActionPreference -eq "Stop") { throw $Pipeline.Pipeline.Streams.Error } else { Write-Error "$($Pipeline.Pipeline.Streams.Error)" } } } else { $task.success = $true } # Output $task variable to file. This will obtain by other cmdlet outside function. $task } catch { $task.SuccessStatus = $false $task.ErrorMessageDetail = $_ Write-Error $_ } finally { # Dispose Pipeline $Pipeline.Pipeline.Dispose() } } } begin { # Inherite variable [HashTable]$task = @{} } } # file loaded from path : \functions\Invokation\CommandExecution\RunSpacePool\Private\Receive-ValentiaAsyncResults.ps1 #Requires -Version 3.0 #-- Private Module Function for Async execution --# <# .SYNOPSIS Receives one or more Asynchronous pipeline State. .DESCRIPTION Asynchronous execution required to check status whether it done or not. .NOTES Author: guitarrapc Created: 13/July/2013 .EXAMPLE $AsyncPipelines += Invoke-ValentiaAsyncCommand -RunspacePool $valentia.runspace.pool.instance -ScriptToRun $ScriptToRun -Deploymember $DeployMember -Credential $credential -Verbose Receive-ValentiaAsyncStatus -Pipelines $AsyncPipelines -------------------------------------------- Above will retrieve Async Result #> function Receive-ValentiaAsyncStatus { [Cmdletbinding()] Param ( [Parameter(Position = 0, mandatory = $true, HelpMessage = "An array of Async Pipeline objects, returned by Invoke-ValentiaAsync.")] [System.Collections.Generic.List[AsyncPipeline]] $Pipelines ) foreach($Pipeline in $Pipelines) { [PSCustomObject]@{ HostName = $Pipeline.Pipeline.Commands.Commands.parameters.Value.ComputerName InstanceID = $Pipeline.Pipeline.Instance_Id State = $Pipeline.Pipeline.InvocationStateInfo.State Reason = $Pipeline.Pipeline.InvocationStateInfo.Reason Completed = $Pipeline.AsyncResult.IsCompleted AsyncState = $Pipeline.AsyncResult.AsyncState Error = $Pipeline.Pipeline.Streams.Error } } } # file loaded from path : \functions\Invokation\CommandExecution\RunSpacePool\Private\Receive-ValentiaAsyncStatus.ps1 #Requires -Version 3.0 #-- Private Module Function for AsyncPipelline execution --# function Invoke-ValentiaAsyncPipeline { [CmdletBinding()] param ( [parameter(mandatory = $false)] [scriptBlock]$ScriptBlock, [parameter(mandatory = $true)] [PSCredential]$Credential, [parameter(mandatory = $false)] [hashtable]$TaskParameter, [parameter(mandatory = $true)] [System.Management.Automation.Runspaces.AuthenticationMechanism]$Authentication, [parameter(mandatory = $true)] [bool]$UseSSL ) # Create RunSpacePools [System.Management.Automation.Runspaces.RunspacePool]$valentia.runspace.pool.instance = New-ValentiaRunSpacePool Write-Verbose ("Target Computers : [{0}]" -f ($ComputerNames -join ", ")) $param = @{ RunSpacePool = $valentia.runspace.pool.instance ScriptToRunHash = @{ScriptBlock = $ScriptToRun} credentialHash = @{Credential = $Credential} TaskParameterHash = @{TaskParameter = $TaskParameter} AuthenticationHash = @{Authentication = $Authentication} UseSSL = @{UseSSL = $UseSSL} } $valentia.runspace.asyncPipeline = New-Object 'System.Collections.Generic.List[AsyncPipeline]' foreach ($DeployMember in $valentia.Result.DeployMembers) { $AsyncPipeline = Invoke-ValentiaAsyncCommand @param -Deploymember $DeployMember $valentia.runspace.asyncPipeline.Add($AsyncPipeline) } } # file loaded from path : \functions\Invokation\CommandExecution\RunSpacePool\Private\AsyncPipeline\Invoke-ValentiaAsyncPipeline.ps1 #Requires -Version 3.0 #-- Private Module Function for AsyncPipelline monitor --# function Watch-ValentiaAsyncPipelineStatus { [Cmdletbinding()] Param ( [Parameter(Position = 0, mandatory = $false, HelpMessage = "An array of Async Pipeline objects, returned by Invoke-ValentiaAsync.")] [System.Collections.Generic.List[AsyncPipeline]]$AsyncPipelines ) process { while ((($ReceiveAsyncStatus = (Receive-ValentiaAsyncStatus -Pipelines $AsyncPipelines | group state, hostname -NoElement)) | where name -like "Running*").count -ne 0) { $count++ $completed = $ReceiveAsyncStatus | where name -like "Completed*" $running = $ReceiveAsyncStatus | where name -like "Running*" $statusPercent = ($completed.count/$ReceiveAsyncStatus.count) * 100 # hide progress or not if (-not $quiet -and ($sw.Elapsed.TotalMilliseconds -ge 500)) { # hide progress or not if ($statusPercent -ne 100) { $paramProgress = @{ Activity = 'Async Execution Running Status.... ({0}sec elapsed)' -f $TotalstopwatchSession.Elapsed.TotalSeconds PercentComplete = $statusPercent status = ("{0}/{1}({2:0.00})% Completed" -f $completed.count, $ReceiveAsyncStatus.count, $statusPercent) } Write-Progress @paramProgress $sw.Reset() $sw.Start() } } # Log Current Status if (-not $null -eq $prevRunningCount) { if ($running.count -lt $prevRunningCount) { $ReceiveAsyncStatus.Name | OutValentiaModuleLogHost -hideDataAsString [PSCustomObject]@{ Running = $running.count Completed = $completed.count } | OutValentiaModuleLogHost -hideDataAsString } } $prevRunningCount = $running.count # Wait a moment sleep -Milliseconds $valentia.runspace.async.sleepMS # safety release if ($count -ge $valentia.runspace.async.limitCount) { break } } } end { # Clear Progress bar from Host, YOU MUST CLEAR PROGRESS BAR, other wise host output will be terriblly slow down. Write-Progress "done" "done" -Completed # Dispose variables if (-not ($null -eq $ReceiveAsyncStatus)) { $ReceiveAsyncStatus = $null } } begin { $sw = [System.Diagnostics.Stopwatch]::StartNew() } } # file loaded from path : \functions\Invokation\CommandExecution\RunSpacePool\Private\AsyncPipeline\Watch-ValentiaAsyncPipelineStatus.ps1 #Requires -Version 3.0 #-- Private Module Function for Async execution --# <# .SYNOPSIS Create a PowerShell Runspace Pool. .DESCRIPTION This function returns a runspace pool, a collection of runspaces that PowerShell pipelines can be executed. The number of available pools determines the maximum number of processes that can be running concurrently. This enables multithreaded execution of PowerShell code. .NOTES Author: guitarrapc Created: 13/July/2013 .EXAMPLE $pool = New-ValentiaRunspacePool -minPoolSize 50 -maxPoolSize 50 -------------------------------------------- Above will creates a pool of 10 runspaces #> function New-ValentiaRunSpacePool { [Cmdletbinding()] Param ( [Parameter(Position =0, mandatory = $false, HelpMessage = "Defines the minium number of pipelines that can be concurrently (asynchronously) executed on the pool.")] [int]$minPoolSize = $valentia.runspace.pool.minSize, [Parameter(Position = 1, mandatory = $false, HelpMessage = "Defines the maximum number of pipelines that can be concurrently (asynchronously) executed on the pool.")] [int]$maxPoolSize = $valentia.runspace.pool.maxSize ) try { $sessionstate = [System.Management.Automation.Runspaces.InitialSessionState]::CreateDefault() # RunspaceFactory.CreateRunspacePool (Int32, Int32, InitialSessionState, PSHost) # - Creates a runspace pool that specifies minimum and maximum number of opened runspaces, # and a custom host and initial session state information that is used by each runspace in the pool. $pool = [runspacefactory]::CreateRunspacePool($minPoolSize, $maxPoolSize, $sessionstate, $Host) # Only support STA mode. No MTA mode. $pool.ApartmentState = "STA" # open RunSpacePool $pool.Open() return $pool } catch { $valentia.Result.SuccessStatus += $false $valentia.Result.ErrorMessageDetail += $_ Write-Error $_ } } # file loaded from path : \functions\Invokation\CommandExecution\RunSpacePool\Private\RunSpacePool\New-ValentiaRunSpacePool.ps1 #Requires -Version 3.0 #-- Private Module Function for Async execution --# <# .SYNOPSIS Close and Dispose PowerShell Runspace Pool. .DESCRIPTION This function Close runspace pool, then dispose. .NOTES Author: guitarrapc Created: 14/Feb/2014 .EXAMPLE Remove-ValentiaRunspacePool -RunSpacePool $valentia.runspace.pool.instance #> function Remove-ValentiaRunSpacePool { [Cmdletbinding()] Param ( [Parameter(Position = 0, mandatory = $false, HelpMessage = "Specify RunSpace Pool to close and dispose.")] [System.Management.Automation.Runspaces.RunspacePool]$Pool = $valentia.runspace.pool.instance ) $script:ErrorActionPreference = $valentia.preference.ErrorActionPreference.custom try { if ($Pool) { $Pool.Close() $Pool.Dispose() } } catch { $valentia.Result.SuccessStatus += $false $valentia.Result.ErrorMessageDetail += $_ Write-Error $_ } } # file loaded from path : \functions\Invokation\CommandExecution\RunSpacePool\Private\RunSpacePool\Remove-ValentiaRunSpacePool.ps1 #Requires -Version 3.0 #-- Public Module Functions for Download Files --# # download <# .SYNOPSIS Use BITS Transfer to downlpad a file from remote server. If -Force switch enable, then use smbmapping and copy -force will run. .DESCRIPTION If target path was directory then download files below path. (None recurse) If target path was file then download specific file. .NOTES Author: guitarrapc Created: 14/Aug/2013 .EXAMPLE download -SourcePath c:\logs\white\20130719 -DestinationFolder c:\logs\white -DeployGroup production-g1.ps1 -Directory -Async -------------------------------------------- download remote sourthdirectory items to local destinationfolder in backgroud job. .EXAMPLE download -SourcePath c:\logs\white\20130716\Http.0001.log -DestinationFolder c:\test -DeployGroup.ps1 production-first -File -------------------------------------------- download remote sourth item to local destinationfolder .EXAMPLE download -SourcePath c:\logs\white\20130716 -DestinationFolder c:\test -DeployGroup production-first.ps1 -Directory -------------------------------------------- download remote sourthdirectory items to local destinationfolder in backgroud job. Omit parameter name. #> function Invoke-ValentiaDownload { [CmdletBinding(DefaultParameterSetName = "File")] param ( [Parameter(Position = 0, mandatory = $true, HelpMessage = "Input Client SourcePath to be downloaded.")] [String]$SourcePath, [Parameter(Position = 1, mandatory = $true, HelpMessage = "Input Server Destination Folder to save download items.")] [string]$DestinationFolder = $null, [Parameter(Position = 2, mandatory = $true, HelpMessage = "Input target of deploy clients as [DeployGroup filename you sat at deploygroup Folder] or [ipaddress].")] [string]$DeployGroups, [Parameter(position = 3, ParameterSetName = "File", HelpMessage = "Set this switch to execute command for File. exclusive with Directory Switch.")] [switch]$File = $true, [Parameter(position = 3, ParameterSetName = "Directory", HelpMessage = "Set this switch to execute command for Directory. exclusive with File Switch.")] [switch]$Directory, [Parameter(position = 4, mandatory = $false, HelpMessage = "Set this switch to execute command as Async (Job).")] [switch]$Async = $false, [Parameter(Position = 5, mandatory = $false, HelpMessage = "Input DeployGroup Folder path if changed from default.")] [string]$DeployFolder = (Join-Path $Script:valentia.RootPath ([ValentiaBranchPath]::Deploygroup)), [Parameter(Position = 6, mandatory = $false, HelpMessage = "Set this switch if you want to Force download. This will smbmap with source folder and Copy-Item -Force. (default is BitTransfer)")] [switch]$force = $false, [Parameter(Position = 7, mandatory = $false, HelpMessage = "Return success result even if there are error.")] [bool]$SkipException = $false, [Parameter(Position = 8, mandatory = $false, HelpMessage = "Input PSCredential to use for wsman.")] [PSCredential]$Credential = (Get-ValentiaCredential) ) try { ### Begin $ErrorActionPreference = $valentia.preference.ErrorActionPreference.custom # Initialize Stopwatch [decimal]$TotalDuration = 0 $TotalstopwatchSession = [System.Diagnostics.Stopwatch]::StartNew() # Initialize Errorstatus $SuccessStatus = $ErrorMessageDetail = @() # Get Start Time $TimeStart = (Get-Date).DateTime # Import default Configurations & Modules if ($PSBoundParameters['Verbose']) { # Import default Configurations $valeWarningMessages.warn_import_configuration | Write-ValentiaVerboseDebug Import-ValentiaConfiguration -Verbose # Import default Modules $valeWarningMessages.warn_import_modules | Write-ValentiaVerboseDebug Import-valentiaModules -Verbose } else { Import-ValentiaConfiguration Import-valentiaModules } # Log Setting New-ValentiaLog # Obtain DeployMember IP or Hosts for BITsTransfer "Get hostaddresses to connect." | Write-ValentiaVerboseDebug $DeployMembers = Get-ValentiaGroup -DeployFolder $DeployFolder -DeployGroup $DeployGroups if ($DeployMembers.SuccessStatus -eq $false) { $SuccessStatus += $DeployMembers.SuccessStatus $ErrorMessageDetail += $DeployMembers.ErrorMessageDetail } # Parse Network Source ("Parsing Network SourcePath {0} as :\ should change to $." -f $SourcrePath) | Write-ValentiaVerboseDebug $SourcePath = "$SourcePath".Replace(":","$") # Show Stopwatch for Begin section $TotalDuration = $TotalstopwatchSession.Elapsed.TotalSeconds Write-Verbose ("`t`tDuration Second for Begin Section: {0}" -f $TotalDuration) "" ### Process ("Downloading {0} from Target Computer : [{1}] `n" -f $SourcePath, $DeployMembers) | Write-ValentiaVerboseDebug # Stopwatch [decimal]$DurationTotal = 0 # Create PSSession for each DeployMember foreach ($DeployMember in $DeployMembers){ # Stopwatch $stopwatchSession = [System.Diagnostics.Stopwatch]::StartNew() # Set Source $Source = Join-Path "\\" $(Join-Path "$DeployMember" "$SourcePath") if (Test-Path $Source) { if ($Directory) { # Set Source files in source try { # Remove last letter of \ or / if (($Source[-1] -eq "\") -or ($Source[-1] -eq "/")) { $Source = $Source.Substring(0,($Source.Length-1)) } # Get File Information - No recurse $SourceFiles = Get-ChildItem -Path $Source } catch { $SuccessStatus += $false $ErrorMessageDetail += $_ throw $_ } } elseif ($File) { # Set Source files in source try { # Get File Information $SourceFiles = Get-Item -Path $Source if ($SourceFiles.Attributes -eq "Directory") { $SuccessStatus += $false $ErrorMessageDetail += "Target is Directory, you must set Filename with -File Switch." throw "Target is Directory, you must set Filename with -File Switch." } } catch { $SuccessStatus += $false $ErrorMessageDetail += $_ throw $_ } } else { $SuccessStatus += $false $ErrorMessageDetail += $_ throw "Missing File or Directory switch. Please set -File or -Directory Switch to specify download type." } # Set Destination with date and DeproyMemberName if ($DestinationFolder -eq $null) { $DestinationFolder = $(Join-Path $Script:valentia.RootPath ([ValentiaBranchPath]::Download)) } $Date = (Get-Date).ToString("yyyyMMdd") $DestinationPath = Join-Path $DestinationFolder $Date $Destination = Join-Path $DestinationPath $DeployMember # Create Destination if not exist if (-not(Test-Path $Destination)) { New-Item -Path $Destination -ItemType Directory -Force > $null } if ($force) { # Show Start-BitsTransfer Parameter ("Downloading {0} from {1}." -f $SourceFiles, $DeployMember) | Write-ValentiaVerboseDebug Write-Verbose ("DeployFolder : {0}" -f $DeployFolder) Write-Verbose ("DeployMembers : {0}" -f $DeployMembers) Write-Verbose ("DeployMember : {0}" -f $DeployMember) Write-Verbose ("Source : {0}" -f $Source) Write-Verbose ("Destination : {0}" -f $Destination) Write-Verbose "Aync Mode : You cannot use Async switch with force" # Get Cimsession for target Computer "cim : New-CimSession to the ComputerName '{0}'" -f $DeployMember | Write-ValentiaVerboseDebug $cim = New-CimSession -Credential $Credential -ComputerName $DeployMember # Create SMB Mapping to target parent directory if ($Directory) { "Directory switch Selected" | Write-ValentiaVerboseDebug $smbRemotePath = (Get-Item $Source).FullName } elseif ($file) { "File switch Selected" | Write-ValentiaVerboseDebug $smbRemotePath = (Get-Item $source).DirectoryName } # Running Copy-Item cmdlet, switch with $force try { #Only start download for file. foreach($SourceFile in $SourceFiles) { if (-not((Get-Item $SourceFile.fullname).Attributes -eq "Directory")) { Write-Warning ("Downloading {0} from {1} to {2}" -f ($SourceFile).fullname, $DeployMember, $Destination) $ScriptToRun = "Copy-Item -Path $(($SourceFile).fullname) -Destination $Destination -Force" Copy-Item -Path $(($SourceFile).fullname) -Destination $Destination -Force } } } catch [System.Management.Automation.ActionPreferenceStopException] { $SuccessStatus += $false $ErrorMessageDetail += $_ # Show Error Message throw $_ } finally { # Stopwatch $Duration = $stopwatchSession.Elapsed.TotalSeconds Write-Verbose ("Session duration Second : {0}" -f $Duration) "" } } else # Not Force Swtich { # Show Start-BitsTransfer Parameter ("Downloading {0} from {1}." -f $SourceFiles, $DeployMember) | Write-ValentiaVerboseDebug Write-Verbose ("DeployFolder : {0}" -f $DeployFolder) Write-Verbose ("DeployMembers : {0}" -f $DeployMembers) Write-Verbose ("DeployMember : {0}" -f $DeployMember) Write-Verbose ("Source : {0}" -f $Source) Write-Verbose ("Destination : {0}" -f $Destination) Write-Verbose ("Aync Mode : {0}" -f $Async) # Running Bits Transfer, switch with $Async and no $Async try { switch ($true) { # Async Transfer $Async { try { $ScriptToRun = "Start-BitsTransfer -Source $(($SourceFile).fullname) -Destination $Destination -Credential $Credential -Asynchronous -DisplayName $DeployMember -Priority High -TransferType Download" foreach($SourceFile in $SourceFiles) { try { #Only start download for file. if (-not((Get-Item $SourceFile.fullname).Attributes -eq "Directory")) { # Run Job Write-Warning ("Async Downloading {0} from {1} to {2}" -f ($SourceFile).fullname, $DeployMember, $Destination) $Job = Start-BitsTransfer -Source $(($SourceFile).fullname) -Destination $Destination -Credential $Credential -Asynchronous -DisplayName $DeployMember -Priority High -TransferType Download # Waiting for complete job $Sleepms = 10 "Current States was {0}" -f $Job.JobState | Write-ValentiaVerboseDebug } } catch { $SuccessStatus += $false $ErrorMessageDetail += $_ # Show Error Message throw $_ } } # Retrieving transfer status and monitor for transffered $Sleepms = 10 while (((Get-BitsTransfer).JobState -contains "Transferring") -or ((Get-BitsTransfer).JobState -contains "Connecting") -or ((Get-BitsTransfer).JobState -contains "Queued")) ` { "Current Job States was {0}, waiting for {1} ms {2}" -f ((Get-BitsTransfer).JobState | sort -Unique), $Sleepms, (((Get-BitsTransfer | where JobState -eq "Transferred").count) / $((Get-BitsTransfer).count)) | Write-ValentiaVerboseDebug Sleep -Milliseconds $Sleepms } # Retrieve all files when completed Get-BitsTransfer | Complete-BitsTransfer } catch { $SuccessStatus += $false $ErrorMessageDetail += $_ # Show Error Message throw $_ } finally { # Delete all not compelte job Get-BitsTransfer | Remove-BitsTransfer # Stopwatch $Duration = $stopwatchSession.Elapsed.TotalSeconds Write-Verbose ("Session duration Second : {0}" -f $Duration) "" $DurationTotal += $Duration } } default { # NOT Async Transfer try { $ScriptToRun = "Start-BitsTransfer -Source $(($SourceFiles).fullname) -Destination $Destination -Credential $Credential -TransferType Download" foreach($SourceFile in $SourceFiles) { #Only start download for file. if (-not((Get-Item $SourceFile.fullname).Attributes -eq "Directory")) { Write-Warning ("Downloading {0} from {1} to {2}" -f ($SourceFile).fullname, $DeployMember, $Destination) Start-BitsTransfer -Source $(($SourceFile).fullname) -Destination $Destination -Credential $Credential -TransferType Download } } } catch [System.Management.Automation.ActionPreferenceStopException] { $SuccessStatus += $false $ErrorMessageDetail += $_ # Show Error Message throw $_ } finally { # Delete all not compelte job Get-BitsTransfer | Remove-BitsTransfer # Stopwatch $Duration = $stopwatchSession.Elapsed.TotalSeconds Write-Verbose ("Session duration Second : {0}" -f $Duration) "" } } } } catch { # Show Error Message Write-Error $_ # Set ErrorResult $SuccessStatus += $false $ErrorMessageDetail += $_ } } } else { Write-Warning ("{0} could find from {1}. Skip to next." -f $Source, $DeployGroups) } } ### End Write-Verbose "All transfer with BitsTransfer had been removed." } catch { $SuccessStatus += $false $ErrorMessageDetail += $_ if (-not $SkipException) { throw $_ } } finally { # obtain Result $resultParam = @{ StopWatch = $TotalstopwatchSession Cmdlet = $($MyInvocation.MyCommand.Name) TaskFileName = $TaskFileName DeployGroups = $DeployGroups SkipException = $SkipException Quiet = $PSBoundParameters.ContainsKey("quiet") -and $quiet } Out-ValentiaResult @resultParam # Cleanup valentia Environment Invoke-ValentiaClean } } # file loaded from path : \functions\Invokation\Download\Invoke-ValentiaDownload.ps1 #Requires -Version 3.0 #-- ping Connection to the host --# # PingAsync <# .SYNOPSIS Ping to the host by IP Address Asynchronous .DESCRIPTION This Cmdlet will ping and get reachability to the host. .NOTES Author: guitarrapc Created: 03/Feb/2014 .EXAMPLE Ping-ValentiaGroupAsync production-hoge.ps1 -------------------------------------------- Ping production-hoge.ps1 from deploy group branch path #> function Ping-ValentiaGroupAsync { [OutputType([Valentia.CS.PingResponse[]])] [CmdletBinding()] param ( [Parameter(Position = 0, mandatory = $true, ValueFromPipeLine = 1, ValueFromPipeLineByPropertyName = 1, HelpMessage = "Input target computer name or ipaddress to test ping.")] [string[]]$HostNameOrAddresses, [Parameter(Position = 1, mandatory = $false, HelpMessage = "Input timeout ms wait for the responce answer.")] [ValidateNotNullOrEmpty()] [int]$Timeout = $valentia.ping.timeout, [Parameter(Position = 2, mandatory = $false, HelpMessage = "Input timeout ms wait for the responce answer.")] [ValidateNotNullOrEmpty()] [int]$DnsTimeout = $valentia.ping.timeout, [Parameter(Position = 3, mandatory = $false, HelpMessage = "Change return type to bool only.")] [ValidateNotNullOrEmpty()] [switch]$quiet ) begin { $list = New-Object System.Collections.Generic.List["string"]; } process { $target = (Get-ValentiaGroup -DeployGroup $HostNameOrAddresses); foreach ($item in $target){ $list.Add($item); } } end { if ($quiet) { [Valentia.CS.NetworkInformationExtensions]::PingAsync($list, [TimeSpan]::FromMilliseconds($Timeout), [TimeSpan]::FromMilliseconds($DnsTimeout)).Result.Status; } else { [Valentia.CS.NetworkInformationExtensions]::PingAsync($list, [TimeSpan]::FromMilliseconds($Timeout), [TimeSpan]::FromMilliseconds($DnsTimeout)).Result; } } } # file loaded from path : \functions\Invokation\Ping\Ping-ValentiaGroupAsync.ps1 #Requires -Version 3.0 #-- ping Connection to the host --# # PingAsync <# .SYNOPSIS Monitor host by Ping for selected Second .DESCRIPTION This function will pingasync to the host. You can set Interval seconds and endup limitCount to prevent eternal execution. .NOTES Author: guitarrapc Created: 27/July/2014 .EXAMPLE Watch-ValentiaPingAsyncReplyStatus -deploygroups 192.168.100.100 -DesiredStatus $true -limitCount 1000 | ft -------------------------------------------- Continuous ping to the 192.168.100.100 for sleepSec 1 sec. (default) This will break if host is reachable or when count up to limitCount 1000. #> function Watch-ValentiaPingAsyncReplyStatus { [CmdletBinding()] param ( [parameter(mandatory = $true, position = 0)] [ValidateNotNullOrEmpty()] [string[]]$deploygroups, [parameter(mandatory = $true, position = 1)] [ValidateNotNullOrEmpty()] [bool]$DesiredStatus = $true, [parameter(mandatory = $false, position = 2)] [ValidateNotNullOrEmpty()] [int]$sleepSec = 1, [parameter(mandatory = $false, position = 3)] [ValidateNotNullOrEmpty()] [int]$limitCount = 100 ) process { $i = 0 while ($true) { $date = Get-Date $hash = pingAsync -HostNameOrAddresses $ipaddress ` | %{ Add-Member -InputObject $_ -MemberType NoteProperty -Name Date -Value $date -Force -PassThru } Write-Verbose ("Filtering status as '{0}'" -f $DesiredStatus) $hash ` | where IsSuccess -eq $DesiredStatus ` | where HostNameOrAddress -in $ipaddress.IPAddressToString ` | %{$result = $ipaddress.Remove($_.HostNameOrAddress) if ($result -eq $false) { throw "failed to remove ipaddress '{0}' from list" -f $_.HostNameOrAddress } else { Write-Host ("ipaddress '{0}' turned to be DesiredStatus '{1}'" -f "$($_.HostNameOrAddress -join ', ')", $DesiredStatus) -ForegroundColor Green } } $count = ($ipaddress | measure).count if ($count -eq 0) { Write-Host ("HostnameOrAddress '{0}' IsSuccess : '{1}'. break monitoring" -f $($hash.HostNameOrAddress -join ", "), $DesiredStatus) -ForegroundColor Cyan $hash break; } elseif ($i -ge $limitCount) { write-Warning ("exceeed {0} count of sleep. break." -f $limitCount) $hash break; } else { Write-Verbose ("sleep {0} second for next status check." -f $sleepSec) $hash sleep -Seconds $sleepSec $i++ } } } end { $end = Get-Date Write-Host ("Start Time : {0}" -f $start) -ForegroundColor Cyan Write-Host ("End Time : {0}" -f $end) -ForegroundColor Cyan Write-Host ("Total Watch : {0}sec" -f $sw.Elapsed.TotalSeconds) -ForegroundColor Cyan } begin { $start = Get-Date $sw = New-Object System.Diagnostics.Stopwatch $sw.Start() $ipaddress = New-Object 'System.Collections.Generic.List[ipaddress]' Get-ValentiaGroup -DeployGroups $deploygroups | %{$ipaddress.Add($_)} } } # file loaded from path : \functions\Invokation\Ping\Watch-ValentiaPingAsyncReplyStatus.ps1 #Requires -Version 3.0 #-- Public Module Functions for Sync Files or Directories--# # Sync <# .SYNOPSIS Use fastcopy.exe to Sync Folder for Diff folder/files not consider Diff from remote server. .DESCRIPTION You must install fastcopy.exe to use this function. .NOTES Author: gutiarrapc Created: 13/July/2013 .EXAMPLE Sync -Source sourcepath -Destination desitinationSharePath -DeployGroup DeployGroup.ps1 -------------------------------------------- Sync sourthpath and destinationsharepath directory in Diff mode. (Will not delete items but only update to add new) .EXAMPLE Sync c:\deployment\upload c:\deployment\upload 192.168.1.100 -------------------------------------------- Sync c:\deployment\upload directory and remote server listed in new.ps1 c:\deployment\upload directory in Diff mode. (Will not delete items but only update to add new) .EXAMPLE Sync -Source c:\upload.txt -Destination c:\share\ -DeployGroup 192.168.1.100,192.168.1.102 -------------------------------------------- Sync c:\upload.txt file and c:\share directory in Diff mode. (Will not delete items but only update to add new) #> function Invoke-ValentiaSync { [CmdletBinding()] param ( [Parameter(Position = 0, mandatory = $true, HelpMessage = "Input Deploy Server Source Folder Sync to Client PC.")] [string]$SourceFolder, [Parameter(Position = 1, mandatory = $true, HelpMessage = "Input Client Destination Folder Sync with Desploy Server.")] [String]$DestinationFolder, [Parameter(Position = 2, mandatory = $true, HelpMessage = "Input target of deploy clients as [DeployGroup filename you sat at deploygroup Folder] or [ipaddress].")] [string]$DeployGroups, [Parameter(Position = 3, mandatory = $false, HelpMessage = "Input DeployGroup Folder path if changed.")] [string]$DeployFolder = (Join-Path $Script:valentia.RootPath ([ValentiaBranchPath]::Deploygroup)), [Parameter(Position = 4, mandatory = $false, HelpMessage = "Return success result even if there are error.")] [bool]$SkipException = $false, [Parameter(Position = 5, mandatory = $false, HelpMessage = "Input PSCredential to use for wsman.")] [PSCredential]$Credential = (Get-ValentiaCredential), [Parameter(Position = 6, mandatory = $false, HelpMessage = "Input fastCopy.exe location folder if changed.")] [string]$FastCopyFolder = $valentia.fastcopy.folder, [Parameter(Position = 7, mandatory = $false, HelpMessage = "Input fastCopy.exe name if changed.")] [string]$FastcopyExe = $valentia.fastcopy.exe ) try { ### Begin $ErrorActionPreference = $valentia.preference.ErrorActionPreference.custom # Initialize Stopwatch [decimal]$TotalDuration = 0 $TotalstopwatchSession = [System.Diagnostics.Stopwatch]::StartNew() # Initialize Errorstatus $SuccessStatus = $ErrorMessageDetail = @() # Get Start Time $TimeStart = (Get-Date).DateTime # Import default Configurations & Modules if ($PSBoundParameters['Verbose']) { # Import default Configurations $valeWarningMessages.warn_import_configuration | Write-ValentiaVerboseDebug Import-ValentiaConfiguration -Verbose # Import default Modules $valeWarningMessages.warn_import_modules | Write-ValentiaVerboseDebug Import-valentiaModules -Verbose } else { Import-ValentiaConfiguration Import-valentiaModules } # Log Setting New-ValentiaLog # Check FastCopy.exe path "Checking FastCopy Folder is exist or not." | Write-ValentiaVerboseDebug if (-not(Test-Path $FastCopyFolder)) { New-Item -Path $FastCopyFolder -ItemType Directory } # Set FastCopy.exe path Write-Verbose "Set FastCopy.exe path." $FastCopy = Join-Path $FastCopyFolder $FastcopyExe # Check SourceFolder Exist or not if (-not(Test-Path $SourceFolder)) { $SuccessStatus += $false $ErrorMessageDetail += "SourceFolder [ $SourceFolder ] not found exeptions! exit job." throw "SourceFolder [ {0} ] not found exeptions! exit job." -f $SourceFolder } # Obtain DeployMember IP or Hosts for FastCopy "Get hostaddresses to connect." | Write-ValentiaVerboseDebug $DeployMembers = Get-valentiaGroup -DeployFolder $DeployFolder -DeployGroup $DeployGroups # Parse Network Destination Path ("Parsing Network Destination Path {0} as :\ should change to $." -f $DestinationFolder) | Write-ValentiaVerboseDebug $DestinationPath = "$DestinationFolder".Replace(":","$") # Safety exit for root drive if ($SourceFolder.Length -ge 3) { Write-Verbose ("SourceFolder[-2]`t:`t$($SourceFolder[-2])") Write-Verbose ("SourceFolder[-1]`t:`t$($SourceFolder[-1])") if (($SourceFolder[-2] + $SourceFolder[-1]) -in (":\",":/")) { $SuccessStatus += $false $ErrorMessageDetail += ("SourceFolder path was Root Drive [ {0} ] exception! Exist for safety." -f $SourceFolder) throw ("SourceFolder path was Root Drive [ {0} ] exception! Exist for safety." -f $SourceFolder) } } # Show Stopwatch for Begin section $TotalDuration = $TotalstopwatchSession.Elapsed.TotalSeconds Write-Verbose ("`t`tDuration Second for Begin Section: {0}" -f $TotalDuration) "" ### Process Write-Warning "Starting Sync Below files" Write-Verbose (" Syncing {0} to Target Computer : [{1}] {2} `n" -f $SourceFolder, $DeployMembers, $DestinationFolder) (Get-ChildItem $SourceFolder).FullName # Stopwatch [decimal]$DurationTotal = 0 foreach ($DeployMember in $DeployMembers) { # Stopwatch $stopwatchSession = [System.Diagnostics.Stopwatch]::StartNew() # Create Destination $Destination = Join-Path "\\" $(Join-Path "$DeployMember" "$DestinationPath") # Set FastCopy.exe Argument for Sync $FastCopyArgument = "/cmd=sync /bufsize=512 /speed=full /wipe_del=FALSE /acl /stream /reparse /force_close /estimate /error_stop=FALSE /log=True /logfile=""$($valentia.log.fullPath)"" ""$SourceFolder"" /to=""$Destination""" # Run FastCopy Write-Warning ("[{0}]:Uploading {1} to {2}." -f $DeployMember ,$SourceFolder, $Destination) Write-Verbose ("FastCopy : {0}" -f $FastCopy) Write-Verbose ("FastCopyArgument : {0}" -f $FastCopyArgument) if (Ping-ValentiaGroupAsync -HostNameOrAddresses $DeployMember) { try { 'Command : Start-Process $FastCopy -ArgumentList $FastCopyArgument -Wait -PassThru -Credential $Credential' | Write-ValentiaVerboseDebug $Result = Start-Process $FastCopy -ArgumentList $FastCopyArgument -Wait -PassThru -Credential $Credential } catch { Write-Error $_ $SuccessStatus += $false $ErrorMessageDetail += $_ } } else { Write-Error ("Target Host {0} unreachable. Check DeployGroup file [ {1} ] again" -f $DeployMember, $DeployGroups) $SuccessStatus += $false $ErrorMessageDetail += ("Target Host {0} unreachable. Check DeployGroup file [ {1} ] again" -f $DeployMember, $DeployGroups) } # Stopwatch $Duration = $stopwatchSession.Elapsed.TotalSeconds Write-Verbose ("Session duration Second : {0}" -f $Duration) "" $DurationTotal += $Duration } ### End "All Sync job complete." | Write-ValentiaVerboseDebug if (Test-Path $valentia.log.fullPath) { if (-not((Select-String -Path $valentia.log.fullPath -Pattern "No Errors").count -ge $DeployMembers.count)) { $SuccessStatus += $false $ErrorMessageDetail += ("One or more host was reachable with ping, but not authentiacate to DestinationFolder [ {0} ]" -f $DestinationFolder) Write-Error ("One or more host was reachable with ping, but not authentiacate to DestinationFolder [ {0} ]" -f $DestinationFolder) } } else { $SuccessStatus += $false $ErrorMessageDetail += ("None of the host was reachable with ping with DestinationFolder [ {0} ]" -f $DestinationFolder) Write-Error ("None of the host was reachable with ping with DestinationFolder [ {0} ]" -f $DestinationFolder) } } catch { $SuccessStatus += $false $ErrorMessageDetail += $_ if (-not $SkipException) { throw $_ } } finally { # Show Stopwatch for Total section $TotalDuration += $TotalstopwatchSession.Elapsed.TotalSeconds Write-Verbose ("`t`tTotal duration Second`t: {0}" -f $TotalDuration) # Get End Time $TimeEnd = (Get-Date).DateTime # obtain Result $CommandResult = [ordered]@{ Success = !($SuccessStatus -contains $false) TimeStart = $TimeStart TimeEnd = $TimeEnd TotalDuration = $TotalDuration Module = "$($MyInvocation.MyCommand.Module)" Cmdlet = "$($MyInvocation.MyCommand.Name)" Alias = "$((Get-Alias -Definition $MyInvocation.MyCommand.Name).Name)" ScriptBlock = "Start-Process $FastCopy -ArgumentList $FastCopyArgument -Wait" DeployGroup = "$DeployGroups" TargetHosCount = $($DeployMembers.count) TargetHosts = "$DeployMembers" Result = $result SkipException = $SkipException ErrorMessage = $($ErrorMessageDetail | where {$_ -ne $null} | sort -Unique) } # show result $quiet = $PSBoundParameters.ContainsKey("quiet") -and $quiet WriteValentiaResultHost -quiet $quiet -CommandResult $CommandResult # output result OutValentiaResultLog -CommandResult $CommandResult -Append # Cleanup valentia Environment Invoke-ValentiaClean } } # file loaded from path : \functions\Invokation\Sync\Invoke-ValentiaSync.ps1 #Requires -Version 3.0 #-- Public Module Functions for Upload Files --# # upload <# .SYNOPSIS Use BITS Transfer to upload a file to remote server. .DESCRIPTION This function supports multiple file transfer, if you want to fix file in list then use uploadList function. .NOTES Author: guitarrapc Created: 13/July/2013 .EXAMPLE upload -SourcePath C:\hogehoge.txt -DestinationPath c:\ -DeployGroup production-first.ps1 -File -------------------------------------------- upload file to destination for hosts written in production-first.ps1 .EXAMPLE upload -SourcePath C:\deployment\Upload -DestinationPath c:\ -DeployGroup production-first.ps1 -Directory -------------------------------------------- upload folder to destination for hosts written in production-first.ps1 .EXAMPLE upload C:\hogehoge.txt c:\ production-first -Directory production-fist.ps1 -Async -------------------------------------------- upload folder as Background Async job for hosts written in production-first.ps1 .EXAMPLE upload C:\hogehoge.txt c:\ production-first -Directory 192.168.0.10 -Async -------------------------------------------- upload file to Directory as Background Async job for host ip 192.168.0.10 .EXAMPLE upload C:\hogehoge* c:\ production-first -Directory production-fist.ps1 -Async -------------------------------------------- upload files in target to Directory as Background Async job for hosts written in production-first.ps1 #> function Invoke-ValentiaUpload { [CmdletBinding(DefaultParameterSetName = "File")] param ( [Parameter(Position = 0, mandatory = $true, HelpMessage = "Input Deploy Server SourcePath to be uploaded.")] [string]$SourcePath, [Parameter(Position = 1, mandatory = $true, HelpMessage = "Input Clinet DestinationPath to save upload items.")] [String]$DestinationPath = $null, [Parameter(Position = 2, mandatory = $true, HelpMessage = "Input target of deploy clients as [DeployGroup filename you sat at deploygroup Folder] or [ipaddress].")] [string]$DeployGroups, [Parameter(position = 3, mandatory = $false, ParameterSetName = "File", HelpMessage = "Set this switch to execute command for File. exclusive with Directory Switch.")] [switch]$File = $null, [Parameter(position = 3, mandatory = $false, ParameterSetName = "Directory", HelpMessage = "Set this switch to execute command for Directory. exclusive with File Switch.")] [switch]$Directory, [Parameter(Position = 4, mandatory = $false, HelpMessage = "Set this switch to execute command as Async (Job).")] [switch]$Async = $false, [Parameter(Position = 5, mandatory = $false, HelpMessage = "Input DeployGroup Folder path if changed from default.")] [string]$DeployFolder = (Join-Path $Script:valentia.RootPath ([ValentiaBranchPath]::Deploygroup)), [Parameter(Position = 6, mandatory = $false, HelpMessage = "Input PSCredential to use for wsman.")] [PSCredential]$Credential = (Get-ValentiaCredential), [Parameter(Position = 7, mandatory = $false, HelpMessage = "Return success result even if there are error.")] [bool]$SkipException = $false ) try { ### Begin $ErrorActionPreference = $valentia.preference.ErrorActionPreference.custom # Initialize Stopwatch [decimal]$TotalDuration = 0 $TotalstopwatchSession = [System.Diagnostics.Stopwatch]::StartNew() # Initialize Errorstatus $SuccessStatus = $ErrorMessageDetail = @() # Get Start Time $TimeStart = (Get-Date).DateTime # Import default Configurations & Modules if ($PSBoundParameters['Verbose']) { # Import default Configurations $valeWarningMessages.warn_import_configuration | Write-ValentiaVerboseDebug Import-ValentiaConfiguration -Verbose # Import default Modules $valeWarningMessages.warn_import_modules | Write-ValentiaVerboseDebug Import-valentiaModules -Verbose } else { Import-ValentiaConfiguration Import-valentiaModules } # Log Setting New-ValentiaLog # Obtain DeployMember IP or Hosts for BITsTransfer "Get hostaddresses to connect." | Write-ValentiaVerboseDebug $DeployMembers = Get-valentiaGroup -DeployFolder $DeployFolder -DeployGroup $DeployGroups # Parse Network Destination Path ("Parsing Network Destination Path {0} as :\ should change to $." -f $DestinationFolder) | Write-ValentiaVerboseDebug $DestinationPath = "$DestinationPath".Replace(":","$") # Show Stopwatch for Begin section $TotalDuration = $TotalstopwatchSession.Elapsed.TotalSeconds Write-Verbose ("`t`tDuration Second for Begin Section: {0}" -f $TotalDuration) "" ### Process ("Uploading {0} to Target Computer : [{1}] `n" -f $SourcePath, $DeployMembers) | Write-ValentiaVerboseDebug # Stopwatch [decimal]$DurationTotal = 0 # Create PSSession for each DeployMember foreach ($DeployMember in $DeployMembers) { # Stopwatch $stopwatchSession = [System.Diagnostics.Stopwatch]::StartNew() # Set Destination $Destination = Join-Path "\\" $(Join-Path "$DeployMember" "$DestinationPath") if ($Directory) { # Set Source files in source try { # No recurse $SourceFiles = Get-ChildItem -Path $SourcePath } catch { $SuccessStatus += $false $ErrorMessageDetail += $_ throw $_ } } elseif ($File) { # Set Source files in source try { # No recurse $SourceFiles = Get-Item -Path $SourcePath if ($SourceFiles.Attributes -eq "Directory") { $SuccessStatus += $false $ErrorMessageDetail += "Target is Directory, you must set Filename with -File Switch." throw "Target is Directory, you must set Filename with -File Switch." } } catch { $SuccessStatus += $false $ErrorMessageDetail += $_ throw $_ } } else { $SuccessStatus += $false $ErrorMessageDetail += $_ throw "Missing File or Directory switch. Please set -File or -Directory Switch to specify download type." } # Show Start-BitsTransfer Parameter Write-Warning ("[{0}]:Uploading {1} to {2}." -f $DeployMember,"$($SourceFiles.Name)", $Destination) Write-Verbose ("DestinationDeployFolder : {0}" -f $DeployFolder) Write-Verbose ("Aync Mode : {0}" -f $Async) if (Test-Path $SourcePath) { try { switch ($true) { # Async Transfer $Async { $ScriptToRun = "Start-BitsTransfer -Source $(($Sourcefile).FullName) -Destination $Destination -Credential $Credential -Asynchronous -DisplayName $DeployMember -Priority High -TransferType Upload" try { foreach ($SourceFile in $SourceFiles) { try { # Run Job ("Running Async Job upload to {0}" -f $DeployMember) | Write-ValentiaVerboseDebug $Job = Start-BitsTransfer -Source $(($Sourcefile).FullName) -Destination $Destination -Credential $Credential -Asynchronous -DisplayName $DeployMember -Priority High -TransferType Upload # Waiting for complete job $Sleepms = 10 } catch { $SuccessStatus += $false $ErrorMessageDetail += $_ # Show Error Message throw $_ } } $Sleepms = 10 # Retrieving transfer status and monitor for transffered while (((Get-BitsTransfer).JobState -contains "Transferring") -or ((Get-BitsTransfer).JobState -contains "Connecting") -or ((Get-BitsTransfer).JobState -contains "Queued")) ` { ("Current Job States was {0}, waiting for {1}ms {2}" -f ((Get-BitsTransfer).JobState | sort -Unique), $Sleepms, (((Get-BitsTransfer | where JobState -eq "Transferred").count) / $((Get-BitsTransfer).count))) | Write-ValentiaVerboseDebug Sleep -Milliseconds $Sleepms } # Retrieve all files when completed Get-BitsTransfer | Complete-BitsTransfer } catch { $SuccessStatus += $false $ErrorMessageDetail += $_ # Show Error Message throw $_ } finally { # Delete all not compelte job Get-BitsTransfer | Remove-BitsTransfer # Stopwatch $Duration = $stopwatchSession.Elapsed.TotalSeconds Write-Verbose ("Session duration Second : {0}" -f $Duration) "" $DurationTotal += $Duration } } # NOT Async Transfer default { $ScriptToRun = "Start-BitsTransfer -Source $(($SourceFiles).fullname) -Destination $Destination -Credential $Credential -TransferType" try { foreach($SourceFile in $SourceFiles) { #Only start upload for file. if (-not((Get-Item $SourceFile.fullname).Attributes -eq "Directory")) { ("Uploading {0} to {1}'s {2}" -f $(($SourceFile).fullname), $DeployMember, $Destination) | Write-ValentiaVerboseDebug Start-BitsTransfer -Source $(($SourceFile).fullname) -Destination $Destination -Credential $Credential } } } catch [System.Management.Automation.ActionPreferenceStopException] { $SuccessStatus += $false $ErrorMessageDetail += $_ # Show Error Message throw $_ } finally { # Delete all not compelte job Get-BitsTransfer | Remove-BitsTransfer # Stopwatch $Duration = $stopwatchSession.Elapsed.TotalSeconds Write-Verbose ("Session duration Second : {0}" -f $Duration) "" } } } } catch { # Show Error Message Write-Error $_ # Set ErrorResult $SuccessStatus += $false $ErrorMessageDetail += $_ } } else { Write-Warning ("{0} could find from {1}. Skip to next." -f $Source, $DeployGroups) } } ### End } catch { $SuccessStatus += $false $ErrorMessageDetail += $_ if (-not $SkipException) { throw $_ } } finally { # Stopwatch $TotalDuration = $TotalstopwatchSession.Elapsed.TotalSeconds Write-Verbose ("`t`tTotal duration Second`t: {0}" -f $TotalDuration) "" | Out-Default # Get End Time $TimeEnd = (Get-Date).DateTime # obtain Result $CommandResult = [ordered]@{ Success = !($SuccessStatus -contains $false) TimeStart = $TimeStart TimeEnd = $TimeEnd TotalDuration = $TotalDuration Module = "$($MyInvocation.MyCommand.Module)" Cmdlet = "$($MyInvocation.MyCommand.Name)" Alias = "$((Get-Alias -Definition $MyInvocation.MyCommand.Name).Name)" ScriptBlock = "$ScriptToRun" DeployGroup = "$DeployGroups" TargetHosCount = $($DeployMembers.count) TargetHosts = "$DeployMembers" SkipException = $SkipException ErrorMessage = $($ErrorMessageDetail | where {$_ -ne $null} | sort -Unique) } # show result $quiet = $PSBoundParameters.ContainsKey("quiet") -and $quiet WriteValentiaResultHost -quiet $quiet -CommandResult $CommandResult # output result OutValentiaResultLog -CommandResult $CommandResult # Cleanup valentia Environment Invoke-ValentiaClean } } # file loaded from path : \functions\Invokation\Upload\Invoke-ValentiaUpload.ps1 #Requires -Version 3.0 #-- Public Module Functions for Upload Listed Files --# # uploadL <# .SYNOPSIS Use BITS Transfer to upload list files to remote server. .DESCRIPTION This function only support files listed in csv sat in upload context. Make sure destination path format is not "c:\" but use "c$\" as UNC path. .NOTES Author: guitarrapc Created: 13/July/2013 .EXAMPLE uploadList -ListFile list.csv -DeployGroup DeployGroup.ps1 -------------------------------------------- upload sourthfile to destinationfile as define in csv for hosts written in DeployGroup.ps1. # # CSV SAMPLE # # Source, Destination # C:\Deployment\Upload\Upload.txt,C$\hogehoge\Upload.txt # C:\Deployment\Upload\DownLoad.txt,C$\hogehoge\DownLoad.txt .EXAMPLE uploadList list.csv -DeployGroup DeployGroup.ps1 -------------------------------------------- upload sourthfile to destinationfile as define in csv for hosts written in DeployGroup.ps1. You can omit -listFile parameter. # # CSV SAMPLE # # Source, Destination # C:\Deployment\Upload\Upload.txt,C$\hogehoge\Upload.txt # C:\Deployment\Upload\DownLoad.txt,C$\hogehoge\DownLoad.txt #> function Invoke-ValentiaUploadList { [CmdletBinding()] param ( [Parameter(Position = 0, Mandatory, HelpMessage = "Input Clinet DestinationPath to save upload items.")] [string]$ListFile, [Parameter(Position = 1, Mandatory, HelpMessage = "Input target of deploy clients as [DeployGroup filename you sat at deploygroup Folder] or [ipaddress].")] [string]$DeployGroups, [Parameter(Position = 2, mandatory = $false, HelpMessage = "Input DeployGroup Folder path if changed from default.")] [string]$DeployFolder = (Join-Path $Script:valentia.RootPath ([ValentiaBranchPath]::Deploygroup)), [Parameter(Position = 3, mandatory = $false, HelpMessage = "Set this switch to execute command as Async (Job).")] [switch]$Async = $false, [Parameter(Position = 4, mandatory = $false, HelpMessage = "Input PSCredential to use for wsman.")] [PSCredential]$Credential = (Get-ValentiaCredential), [Parameter(Position = 5, mandatory = $false, HelpMessage = "Return success result even if there are error.")] [bool]$SkipException = $false ) try { ### Begin $ErrorActionPreference = $valentia.preference.ErrorActionPreference.custom # Initialize Stopwatch [decimal]$TotalDuration = 0 $TotalstopwatchSession = [System.Diagnostics.Stopwatch]::StartNew() # Initialize Errorstatus $SuccessStatus = $ErrorMessageDetail = @() # Get Start Time $TimeStart = (Get-Date).DateTime # Import default Configurations & Modules if ($PSBoundParameters['Verbose']) { # Import default Configurations $valeWarningMessages.warn_import_configuration | Write-ValentiaVerboseDebug Import-ValentiaConfiguration -Verbose # Import default Modules $valeWarningMessages.warn_import_modules | Write-ValentiaVerboseDebug Import-valentiaModules -Verbose } else { Import-ValentiaConfiguration Import-valentiaModules } # Log Setting New-ValentiaLog # Obtain DeployMember IP or Hosts for BITsTransfer "Get hostaddresses to connect." | Write-ValentiaVerboseDebug $DeployMembers = Get-valentiaGroup -DeployFolder $DeployFolder -DeployGroup $DeployGroups # Set SourcePath to retrieve target File full path (default Upload folder of deployment) $SourceFolder = Join-Path $Script:valentia.RootPath ([ValentiaBranchPath]::Upload) if (-not(Test-Path $SourceFolder)) { ("SourceFolder not found creating {0}" -f $SourceFolder) | Write-ValentiaVerboseDebug New-Item -Path $SourceFolder -ItemType Directory } try { "Defining ListFile full path." | Write-ValentiaVerboseDebug $SourcePath = Join-Path $SourceFolder $ListFile -Resolve } catch { $SuccessStatus += $false $ErrorMessageDetail += $_ throw $_ } # Obtain List of File upload ("Retrive souce file list from {0} `n" -f $SourcePath) | Write-ValentiaVerboseDebug $List = Import-Csv $SourcePath -Delimiter "," # Show Stopwatch for Begin section $TotalDuration = $TotalstopwatchSession.Elapsed.TotalSeconds Write-Verbose ("`t`tDuration Second for Begin Section: {0}" -f $TotalDuration) "" ### Process (" Uploading Files written in {0} to Target Computer : [{1}] `n" -f $SourcePath, $DeployMembers) | Write-ValentiaVerboseDebug # Stopwatch [decimal]$DurationTotal = 0 foreach ($DeployMember in $DeployMembers){ # Stopwatch $stopwatchSession = [System.Diagnostics.Stopwatch]::StartNew() #Create New List $NewList = $List | %{ [PSCustomObject]@{ Source = $_.source Destination = "\\" + $DeployMember + "\" + $($_.destination) } } try { # Run Start-BitsTransfer Write-Warning ("[{0}]: Uploading {1} to {2} ." -f $DeployMember ,"$($NewList.Source)", "$($NewList.Destination)") Write-Verbose ("ListFile : {0}" -f $SourcePath) Write-Verbose ("Aysnc : {0}" -f $Async) if ($Async) { #Command Detail $ScriptToRun = '$NewList | Start-BitsTransfer -Credential $Credential -Async' # Run Start-BitsTransfer retrieving files from List csv with Async switch ("Running Async uploadL to '{0}'" -f $DeployMember) | Write-ValentiaVerboseDebug $BitsJob = $NewList | Start-BitsTransfer -Credential $Credential -Async # Monitoring Bits Transfer States complete $Sleepms = 10 while (((Get-BitsTransfer).JobState -contains "Transferring") -or ((Get-BitsTransfer).JobState -contains "Connecting") -or ((Get-BitsTransfer).JobState -contains "Queued")) ` { ("Current Job States was '{0}', waiting for '{1}' ms '{2}'" -f "$((Get-BitsTransfer).JobState | sort -Unique)", $Sleepms, (((Get-BitsTransfer | where JobState -eq "Transferred").count) / $((Get-BitsTransfer).count))) | Write-ValentiaVerboseDebug sleep -Milliseconds $Sleepms } # Send Complete message to make file from ****.Tmp ("Completing Async uploadL to '{0}'" -f $DeployMember) | Write-ValentiaVerboseDebug # Retrieve all files when completed Get-BitsTransfer | Complete-BitsTransfer } else { #Command Detail $ScriptToRun = "$NewList | Start-BitsTransfer -Credential $Credential" # Run Start-BitsTransfer retrieving files from List csv ("Running Sync uploadL to {0}" -f $DeployMember) | Write-ValentiaVerboseDebug $NewList | Start-BitsTransfer -Credential $Credential } } catch { $SuccessStatus += $false $ErrorMessageDetail += $_ # Show Error Message throw $_ } finally { "Delete all not compelte job" | Write-ValentiaVerboseDebug Get-BitsTransfer | Remove-BitsTransfer # Stopwatch $Duration = $stopwatchSession.Elapsed.TotalSeconds Write-Verbose ("Session duration Second : {0}" -f $Duration) "" } } ### End } catch { $SuccessStatus += $false $ErrorMessageDetail += $_ if (-not $SkipException) { throw $_ } } finally { # Stopwatch $TotalDuration = $TotalstopwatchSession.Elapsed.TotalSeconds Write-Verbose ("`t`tTotal duration Second`t: {0}" -f $TotalDuration) "" | Out-Default # Get End Time $TimeEnd = (Get-Date).DateTime # obtain Result $CommandResult = [ordered]@{ Success = !($SuccessStatus -contains $false) TimeStart = $TimeStart TimeEnd = $TimeEnd TotalDuration = $TotalDuration Module = "$($MyInvocation.MyCommand.Module)" Cmdlet = "$($MyInvocation.MyCommand.Name)" Alias = "$((Get-Alias -Definition $MyInvocation.MyCommand.Name).Name)" ScriptBlock = "$ScriptToRun" DeployGroup = "$DeployGroups" TargetHosCount = $($DeployMembers.count) TargetHosts = "$DeployMembers" SkipException = $SkipException ErrorMessage = $($ErrorMessageDetail | where {$_ -ne $null} | sort -Unique) } # show result $quiet = $PSBoundParameters.ContainsKey("quiet") -and $quiet WriteValentiaResultHost -quiet $quiet -CommandResult $CommandResult # output result OutValentiaResultLog -CommandResult $CommandResult # Cleanup valentia Environment Invoke-ValentiaClean } } # file loaded from path : \functions\Invokation\Upload\Invoke-ValentiaUploadList.ps1 |