Windows PowerShell module added
This commit is contained in:
		| @@ -0,0 +1,29 @@ | |||||||
|  | <# | ||||||
|  | Naming convention: | ||||||
|  |  | ||||||
|  | == Normal variables | ||||||
|  | ** Set: $NormalVar = 123 | ||||||
|  | ** Get: Write-Host $NormalVar | ||||||
|  |  | ||||||
|  | == Script-scope variables | ||||||
|  | ** Set: $script:__ScriptScopeVar = 123 | ||||||
|  | ** Get: Write-Host $__ScriptScopeVar | ||||||
|  |  | ||||||
|  | == Global-scope variables | ||||||
|  | ** Set: $global:__GlobalScopeVar__ = 123 | ||||||
|  | ** Get: Write-Host $__GlobalScopeVar__ | ||||||
|  | #> | ||||||
|  |  | ||||||
|  | $script:__ModulePath = $PsScriptRoot | ||||||
|  | $script:__ModuleName = $PsScriptRoot.Split("\")[-1] | ||||||
|  | $script:__DefaultLogPath = [IO.Path]::Combine([IO.Path]::GetTempPath(), "PowerShell_$__ModuleName.log") | ||||||
|  |  | ||||||
|  |  | ||||||
|  | $script:__RequiredModules = @("ServerManager", "DnsClient") | ||||||
|  | $script:__ImportModulesExplicitely = $true | ||||||
|  | $script:__ImportModulesErrorAction = "Stop" | ||||||
|  |  | ||||||
|  |  | ||||||
|  | $global:__StopExecutionThrowsExeption__ = $true | ||||||
|  | $global:__StopExecutionExitsSession__ = $false | ||||||
|  |  | ||||||
										
											Binary file not shown.
										
									
								
							| @@ -0,0 +1,34 @@ | |||||||
|  | # Import config first | ||||||
|  | . "$PsScriptRoot\Config.ps1" | ||||||
|  |  | ||||||
|  | # Import functions from 'Include' subfolder | ||||||
|  | Get-ChildItem "$PsScriptRoot\Include" -Filter "*.ps1" | | ||||||
|  |     ForEach-Object { | ||||||
|  |         . "$($_.FullName)" | ||||||
|  |     } | ||||||
|  |  | ||||||
|  | trap { Stop-Execution $_ } | ||||||
|  |  | ||||||
|  | Export-ModuleMember -Function * -Alias * | ||||||
|  |  | ||||||
|  | if ($__ImportModulesExplicitely) { | ||||||
|  |     foreach ($Module in $__RequiredModules) { | ||||||
|  |         Write-Log "Importing module '$Module' ..." | ||||||
|  |         Import-Module -Name "$Module" -ErrorAction "$__ImportModulesErrorAction" | ||||||
|  |     } | ||||||
|  | } | ||||||
|  |  | ||||||
|  | Write-Log "Module loaded from '$PsScriptRoot'" | ||||||
|  |  | ||||||
|  | #------------------------------------------------------------------------------- | ||||||
|  |  | ||||||
|  | switch ($Args[0]) { | ||||||
|  |     'installTo' { | ||||||
|  |         Install-Module -InstallPath $args[1] -ModulePath $PsScriptRoot | ||||||
|  |     } | ||||||
|  |     'register' { | ||||||
|  |         Register-Module "$PsScriptRoot" | ||||||
|  |     } | ||||||
|  |     default { | ||||||
|  |     } | ||||||
|  | } | ||||||
| @@ -0,0 +1,747 @@ | |||||||
|  | Function Stop-Execution { | ||||||
|  | <# | ||||||
|  | .SYNOPSIS | ||||||
|  | Breaks execution with specified error code. | ||||||
|  |  | ||||||
|  | .DESCRIPTION | ||||||
|  | Function break script execution with error code provided. Error code may be 0 in case of non-error stop. | ||||||
|  |  | ||||||
|  | It also tries to parse ErrorRecord or Exception object (if provided) and logs this information. | ||||||
|  | #> | ||||||
|  | 	param ( | ||||||
|  | 		$InputObject = $null, | ||||||
|  | 		[String] $ExitString = "", | ||||||
|  | 		[Int] $ExitCode = 1, | ||||||
|  | 		[Switch] $Success | ||||||
|  | 	) | ||||||
|  | 	 | ||||||
|  | 	Function Do-ExitFailure { | ||||||
|  | 		Write-LogFatal "STOP ($ExitCode): $ExitString" | ||||||
|  |         if ($__StopExecutionThrowsExeption__) { | ||||||
|  |             throw $InputObject | ||||||
|  |         } | ||||||
|  |         elseif ($__StopExecutionExitsSession__) { | ||||||
|  | 		    exit $ExitCode | ||||||
|  |         } | ||||||
|  |         else { | ||||||
|  |             break | ||||||
|  |         } | ||||||
|  | 	} | ||||||
|  | 	 | ||||||
|  | 	Function Do-ExitSuccess { | ||||||
|  | 		Write-LogInfo "STOP (0): $ExitString" | ||||||
|  |         if ($__StopExecutionThrowsExeption__) { | ||||||
|  |             exit 0 | ||||||
|  |         } | ||||||
|  |         elseif ($__StopExecutionExitsSession__) { | ||||||
|  |     		exit 0 | ||||||
|  |         } | ||||||
|  |         else { | ||||||
|  |             break | ||||||
|  |         } | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	if ($Success -eq $true) { | ||||||
|  | 		if ($ExitString -eq "") { | ||||||
|  | 			$ExitString = "Script stopped with NO ERROR." | ||||||
|  | 		} | ||||||
|  | 		Do-ExitSuccess | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	if ($ExitString -ne "") { | ||||||
|  | 		Do-ExitFailure | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  |  | ||||||
|  | 	if ($InputObject -eq $null) { | ||||||
|  | 		$ExitString = "***** SCRIPT INTERRUPTED *****" | ||||||
|  | 		Do-ExitFailure | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  |  | ||||||
|  | 	if ($ExitString -eq "") { | ||||||
|  | 		try { | ||||||
|  | 			$ErrorRecord = [System.Management.Automation.ErrorRecord] $InputObject | ||||||
|  | 			$ExitString = @" | ||||||
|  | $($ErrorRecord.ToString()) | ||||||
|  |  | ||||||
|  | *** Invocation Info *** | ||||||
|  | $($ErrorRecord.InvocationInfo.PositionMessage) | ||||||
|  |  | ||||||
|  | *** CategoryInfo *** | ||||||
|  | $($ErrorRecord.CategoryInfo.ToString()) | ||||||
|  |  | ||||||
|  | *** FullyQualifiedErrorId *** | ||||||
|  | $($ErrorRecord.FullyQualifiedErrorId.ToString()) | ||||||
|  |  | ||||||
|  | *** ScriptStackTrace *** | ||||||
|  | $($ErrorRecord.ScriptStackTrace.ToString()) | ||||||
|  | *** *** *** | ||||||
|  | "@ | ||||||
|  | 		} | ||||||
|  | 		catch { | ||||||
|  | 			$ErrorRecord = $null | ||||||
|  | 			Write-LogWarning "Unable to cast InputObject to [System.Management.Automation.ErrorRecord]" | ||||||
|  | 		} | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  |  | ||||||
|  | 	if ($ExitString -eq "") { | ||||||
|  | 		try { | ||||||
|  | 			$Exception = [System.Exception] $InputObject | ||||||
|  | 			$ExitString = $Exception.ToString() | ||||||
|  | 		} | ||||||
|  | 		catch { | ||||||
|  | 			$Exception = $null | ||||||
|  | 			Write-LogWarning "Unable to cast InputObject to [System.Exception]" | ||||||
|  | 		} | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	 | ||||||
|  | 	if ($ExitString -eq "") { | ||||||
|  | 		try { | ||||||
|  | 			$ExitString = [String] $InputObject | ||||||
|  | 		} | ||||||
|  | 		catch { | ||||||
|  | 			Write-LogWarning "Unable to cast InputObject of type [$($InputObject.GetType())] to any of supported types." | ||||||
|  | 		} | ||||||
|  | 	} | ||||||
|  |      | ||||||
|  | 	Do-ExitFailure | ||||||
|  | } | ||||||
|  |  | ||||||
|  |  | ||||||
|  | Function Set-ComputerName { | ||||||
|  |     param ( | ||||||
|  |         [String] $Name | ||||||
|  |     ) | ||||||
|  |      | ||||||
|  |      | ||||||
|  | 	# Rename the computer | ||||||
|  | 	if ($Name -ne "") { | ||||||
|  | 		if (Test-ComputerName -ComputerName $Name) { | ||||||
|  | 			Stop-Execution -Success -ExitString "Computer name already configured" | ||||||
|  | 		} | ||||||
|  | 		else { | ||||||
|  | 			Write-Log "Renaming computer to '$Name'" | ||||||
|  | 				 | ||||||
|  | 			Rename-Computer -NewName $NewName -Force -ErrorAction Stop | ||||||
|  |  | ||||||
|  | 			Stop-Execution -ExitCode 3010 -ExitString "Please restart the computer now" | ||||||
|  | 		} | ||||||
|  | 	} | ||||||
|  | } | ||||||
|  |  | ||||||
|  |  | ||||||
|  |  | ||||||
|  | Function Test-ComputerName { | ||||||
|  | <# | ||||||
|  | .SYNOPSIS | ||||||
|  | Test if computer name is set, and the computer belongs to specified domain / workgroup. | ||||||
|  |  | ||||||
|  | .DESCRIPTION | ||||||
|  | Function tests the following conditions: | ||||||
|  | * the computer name is equal to the provided one | ||||||
|  | * the computer is a part of domain | ||||||
|  | * the computer belongs to the specified domain | ||||||
|  | * the computer belongs to the specified workgroup | ||||||
|  |  | ||||||
|  | Multiple checks are logically ANDed. | ||||||
|  | #> | ||||||
|  |     [CmdletBinding()] | ||||||
|  | 	param ( | ||||||
|  | 		[String] $ComputerName, | ||||||
|  | 		[String] $DomainName, | ||||||
|  | 		[String] $WorkgroupName, | ||||||
|  | 		[Switch] $PartOfDomain | ||||||
|  | 	) | ||||||
|  | 	process { | ||||||
|  |     	$ComputerSystem = Get-WmiObject Win32_ComputerSystem | ||||||
|  |     	 | ||||||
|  |     	if (($ComputerName -ne "") -and ($ComputerSystem.Name -ne "$ComputerName")) { | ||||||
|  |             Write-Error "ComputerName is not equal to '$ComputerName'" | ||||||
|  |     		return $false | ||||||
|  |     	} | ||||||
|  |     	 | ||||||
|  |     	if (($DomainName -ne "") -and ($ComputerSystem.Domain -ne "$DomainName")) { | ||||||
|  |             Write-Error "DomainName is not equal to '$DomainName'" | ||||||
|  |     		return $false | ||||||
|  |     	} | ||||||
|  |     	 | ||||||
|  |     	if (($WorkgroupName -ne "") -and ($ComputerSystem.Workgroup -ne "$WorkgroupName")) { | ||||||
|  |             Write-Error "WorkgroupName is not equal to '$WorkgroupName'" | ||||||
|  |     		return $false | ||||||
|  |     	} | ||||||
|  |     	 | ||||||
|  |     	if (($PartOfDOmain -eq $true) -and ($ComputerSystem.PartOfDomain -eq $false)) { | ||||||
|  |             Write-Error "Computer is not the part of any domain." | ||||||
|  |     		return $false | ||||||
|  |     	} | ||||||
|  |     	 | ||||||
|  |     	return $true | ||||||
|  |     } | ||||||
|  | } | ||||||
|  |  | ||||||
|  |  | ||||||
|  |  | ||||||
|  | Function Show-EthernetNetworkAdapters { | ||||||
|  |     Get-WmiObject Win32_NetworkAdapter -Filter "PhysicalAdapter = 'True' AND AdapterTypeId = '0'" | | ||||||
|  |         Select-Object 'Index','MACAddress','NetConnectionId' | ||||||
|  | } | ||||||
|  |  | ||||||
|  |  | ||||||
|  |  | ||||||
|  | Function Set-NetworkAdapterConfiguration { | ||||||
|  | <# | ||||||
|  | .SYNOPSIS | ||||||
|  | Set network adapter configuration. | ||||||
|  |  | ||||||
|  | .DESCRIPTION | ||||||
|  |  | ||||||
|  |  | ||||||
|  | .EXAMPLE | ||||||
|  | PS> Set-NetworkAdapterConfiguration -MACAddress aa:bb:cc:dd:ee:ff -Auto | ||||||
|  |  | ||||||
|  | Convert "dynamic" parameters (DHCP) to "static" (manual) for network adapter with MAC address aa:bb:cc:dd:ee:ff | ||||||
|  |  | ||||||
|  | .EXAMPLE | ||||||
|  | PS> Set-NetworkAdapterConfiguration -MACAddress aa:bb:cc:dd:ee:ff -DNSServer "192.168.0.1","192.168.0.2" | ||||||
|  |  | ||||||
|  | Configure DNS servers list for network adapter with MAC address aa:bb:cc:dd:ee:ff | ||||||
|  |  | ||||||
|  | #> | ||||||
|  | 	param ( | ||||||
|  | 		[String] $MACAddress = "", | ||||||
|  | 		 | ||||||
|  | 		[Parameter(ParameterSetName="ManualConfig")] | ||||||
|  | 		[String] $IPAddress = "", | ||||||
|  | 		 | ||||||
|  | 		[Parameter(ParameterSetName="ManualConfig")] | ||||||
|  | 		[String] $IPNetmask = "", | ||||||
|  | 		 | ||||||
|  | 		[Parameter(ParameterSetName="ManualConfig")] | ||||||
|  | 		[String[]] $IPGateway = @(), | ||||||
|  | 		 | ||||||
|  | 		[Parameter(ParameterSetName="ManualConfig")] | ||||||
|  | 		[String[]] $DNSServer = @(), | ||||||
|  | 		 | ||||||
|  | 		[Parameter(ParameterSetName="ManualConfig")] | ||||||
|  | 		[Switch] $FirstAvailable, | ||||||
|  |  | ||||||
|  | 		[String] $Name = "", | ||||||
|  | 		 | ||||||
|  | 		[Parameter(ParameterSetName="AutoConfig",Mandatory=$true)] | ||||||
|  | 		[Switch] $Auto, | ||||||
|  |  | ||||||
|  | 		[Parameter(ParameterSetName="AutoConfig")] | ||||||
|  | 		[Switch] $All | ||||||
|  | 	) | ||||||
|  |      | ||||||
|  | 	Write-Log "Configuring network adapter(s) ..." | ||||||
|  |      | ||||||
|  | 	:SetIPAddress switch($PSCmdlet.ParameterSetName) { | ||||||
|  | 		"AutoConfig" { | ||||||
|  |             Write-Log "'auto' mode" | ||||||
|  |              | ||||||
|  | 			$IPv4RegExp = "\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}" | ||||||
|  | 			 | ||||||
|  | 			if ($All -eq $true) { | ||||||
|  | 				$Filter = { $_.AdapterTypeId -eq 0 } | ||||||
|  | 				$Name = "" | ||||||
|  | 			} | ||||||
|  | 			else { | ||||||
|  | 				$Filter = { $_.MACAddress -eq $MACAddress } | ||||||
|  | 			} | ||||||
|  | 			 | ||||||
|  | 			Get-WmiObject Win32_NetworkAdapter | | ||||||
|  | 				Where-Object $Filter | | ||||||
|  | 				ForEach-Object { | ||||||
|  | 					$NetworkAdapter = $_ | ||||||
|  | 					$AdapterConfig = Get-WmiObject Win32_NetworkAdapterConfiguration | | ||||||
|  | 						Where-Object { $_.Index -eq $NetworkAdapter.DeviceId } | ||||||
|  | 					 | ||||||
|  | 					Write-Log "Configuring '$($NetworkAdapter.Name)' ..." | ||||||
|  | 					 | ||||||
|  | 					for ($i = 0; $i -lt $AdapterConfig.IPAddress.Length; $i++) { | ||||||
|  | 						if ($AdapterConfig.IPAddress[$i] -match $IPv4RegExp) { | ||||||
|  | 							$IPAddress = $AdapterConfig.IPAddress[$i] | ||||||
|  | 							$IPNetmask = $AdapterConfig.IPSubnet[$i] | ||||||
|  | 							$IPGateway = $AdapterConfig.DefaultIPGateway | ||||||
|  |                             $DNSServer = $AdapterConfig.DNSServerSearchOrder | ||||||
|  | 							 | ||||||
|  | 							Write-Log "Setting IP address ($IPAddress), netmask ($IPNetmask) ..." | ||||||
|  | 							$AdapterConfig.EnableStatic($IPAddress, $IPNetmask) | Out-Null | ||||||
|  |                              | ||||||
|  |                             Write-Log "Setting default gateways ($IPGateway) ..." | ||||||
|  | 							$AdapterConfig.SetGateways($IPGateway) | Out-Null | ||||||
|  |                              | ||||||
|  |                             Write-Log "Setting DNS servers ($DNSServer) ..." | ||||||
|  |                             $AdapterConfig.SetDNSServerSearchOrder($DNSServer) | Out-Null | ||||||
|  | 						} | ||||||
|  | 					} | ||||||
|  |                      | ||||||
|  |                     Write-Log "'$($NetworkAdapter.Name)' configured" | ||||||
|  | 				} | ||||||
|  | 		} | ||||||
|  | 		"ManualConfig" { | ||||||
|  |             Write-Log "'manual' mode" | ||||||
|  | 			if ( $FirstAvailable ) { | ||||||
|  |                 Write-Log "Selecting first available network adapter ..." | ||||||
|  | 				$NetworkAdapter = Get-WmiObject Win32_NetworkAdapter | | ||||||
|  | 					Where-Object { $_.AdapterTypeId -eq 0 } | | ||||||
|  | 					Select-Object -First 1 | ||||||
|  | 			} | ||||||
|  | 			else { | ||||||
|  | 				$NetworkAdapter = Get-WmiObject Win32_NetworkAdapter | | ||||||
|  | 					Where-Object { $_.MACAddress -eq $MACAddress } | ||||||
|  | 			} | ||||||
|  | 			 | ||||||
|  | 			if ( $NetworkAdapter -eq $null ) { | ||||||
|  | 				Write-LogError "Network adapter with MAC = '$MACAddress' not found." | ||||||
|  | 				return | ||||||
|  | 			} | ||||||
|  | 			 | ||||||
|  | 			$AdapterConfig = Get-WmiObject Win32_NetworkAdapterConfiguration | | ||||||
|  | 				Where-Object { $_.Index -eq $NetworkAdapter.DeviceId } | ||||||
|  |  | ||||||
|  | 			if (($IPAddress -ne "") -and ($IPNetmask -ne "")) { | ||||||
|  | 				Write-Log "Configuring IP address / netmask for '$($NetworkAdapter.Name)' ..." | ||||||
|  | 				 | ||||||
|  | 				<# | ||||||
|  | 				for ($i = 0; $i -lt $AdapterConfig.IPAddress.Length; $i++) | ||||||
|  | 				{ | ||||||
|  | 					if (($AdapterConfig.IPAddress[$i] -eq $IPAddress) -and ($AdapterConfig.IPSubnet[$i] -eq $IPNetmask)) | ||||||
|  | 					{ | ||||||
|  | 						Write-Log "There is an adapter with required configuration." | ||||||
|  | 						break SetIPAddress | ||||||
|  | 					} | ||||||
|  | 				} | ||||||
|  | 				#> | ||||||
|  | 				Write-Log "Setting IP address $IPAddress, netmask $IPNetmask" | ||||||
|  | 				$AdapterConfig.EnableStatic("$IPAddress", "$IPNetmask") | Out-Null | ||||||
|  | 				 | ||||||
|  | 				Write-Log "IP address configured." | ||||||
|  | 			} | ||||||
|  | 			 | ||||||
|  | 			if ($IPGateway.Count -gt 0) { | ||||||
|  | 				Write-Log "Configuring IP gateway for '$($NetworkAdapter.Name)' ..." | ||||||
|  | 				 | ||||||
|  | 				$AdapterConfig.SetGateways($IPGateway) | Out-Null | ||||||
|  | 				 | ||||||
|  | 				Write-Log "IP gateway configured." | ||||||
|  | 			} | ||||||
|  | 			 | ||||||
|  | 			if ($DNSServer.Count -gt 0) { | ||||||
|  | 				Write-Log "Configuring DNS server(s) for '$($NetworkAdapter.Name)' ..." | ||||||
|  | 				 | ||||||
|  | 				$AdapterConfig.SetDNSServerSearchOrder($DNSServer) | Out-Null | ||||||
|  | 				 | ||||||
|  | 				Write-Log "DNS configured." | ||||||
|  | 			} | ||||||
|  | 		} | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	if ($Name -ne "") { | ||||||
|  | 		Write-Log "Changing adapter name '$($NetworkAdapter.NetConnectionId)' --> '$Name'" | ||||||
|  | 		$NetworkAdapter.NetConnectionId = "$Name" | ||||||
|  | 		$NetworkAdapter.Put() | Out-Null | ||||||
|  | 	} | ||||||
|  | } | ||||||
|  |  | ||||||
|  |  | ||||||
|  |  | ||||||
|  | Function Test-WmiReturnValue { | ||||||
|  | <# | ||||||
|  | .SYNOPSIS | ||||||
|  | Check the ReturnValue property of the object provided. | ||||||
|  |  | ||||||
|  | .DESCRIPTION | ||||||
|  | This funciton checks if ReturnValue property is equal to 0. | ||||||
|  |  | ||||||
|  | === TODO === | ||||||
|  | If it is not, then funtion should try to provide desctiption for the error code based on the WMI object type. | ||||||
|  | WMI object type must be provided explicitely. | ||||||
|  | #> | ||||||
|  | 	param ( | ||||||
|  | 		[Parameter(ValueFromPipeline=$true,Mandatory=$true)] | ||||||
|  | 		$InputObject, | ||||||
|  | 		[String] $Type = "" | ||||||
|  | 	) | ||||||
|  | 		 | ||||||
|  | 	try { | ||||||
|  | 		$ReturnValue = $InputObject.ReturnValue | ||||||
|  | 	} | ||||||
|  | 	catch { | ||||||
|  | 		throw "Property 'ReturnValue' not found on this object" | ||||||
|  | 	} | ||||||
|  | 		 | ||||||
|  | 	if ($ReturnValue -eq 0) { | ||||||
|  | 		Write-Log "WMI operation completed successfully" | ||||||
|  | 	} | ||||||
|  | 	else { | ||||||
|  | 		throw "Operation failed with status code = $ReturnValue" | ||||||
|  | 	} | ||||||
|  | } | ||||||
|  |  | ||||||
|  |  | ||||||
|  |  | ||||||
|  | Function Add-WindowsFeatureWrapper { | ||||||
|  | <# | ||||||
|  | .SYNOPSIS | ||||||
|  | Wraps Install-WindowsFeature function. | ||||||
|  |  | ||||||
|  | .DESCRIPTION | ||||||
|  | This function adds some logic to multiple feature installation. | ||||||
|  |  | ||||||
|  | It fails if any of required features fails. | ||||||
|  |  | ||||||
|  | It reports that reboot required if it is required, or restarts the computer. | ||||||
|  | #> | ||||||
|  | 	param ( | ||||||
|  | 		[Parameter(Mandatory=$true)] | ||||||
|  | 		[String[]] $Name, | ||||||
|  | 		[Switch] $IncludeManagementTools, | ||||||
|  | 		[Switch] $AllowRestart, | ||||||
|  |         [Switch] $NotifyRestart | ||||||
|  | 	) | ||||||
|  | 	 | ||||||
|  |     $RestartNeeded = $false | ||||||
|  |      | ||||||
|  | 	foreach ($Feature in $Name) { | ||||||
|  | 		Write-Log "Installing feature '$Feature' ..." | ||||||
|  | 		$Action = Install-WindowsFeature ` | ||||||
|  | 			-Name $Feature ` | ||||||
|  | 			-IncludeManagementTools:$IncludeManagementTools ` | ||||||
|  | 			-ErrorAction Stop | ||||||
|  | 		 | ||||||
|  | 		if ($Action.Success -eq $true) { | ||||||
|  | 			if ($Action.FeatureResult.RestartNeeded -eq $true) { | ||||||
|  | 				Write-LogWarning "Restart required" | ||||||
|  | 				$RestartNeeded = $true | ||||||
|  | 			} | ||||||
|  | 			Write-Log "Feature '$Feature' installed successfully" | ||||||
|  | 		} | ||||||
|  | 		else { | ||||||
|  | 			Stop-Execution "Failed to install feature '$Feature'" | ||||||
|  | 		} | ||||||
|  | 	} | ||||||
|  | 	 | ||||||
|  |     if ($RestartNeeded) { | ||||||
|  |         Write-Log "Restart required to finish feature(s) installation." | ||||||
|  |         if ($AllowRestart) { | ||||||
|  |             Write-Log "Restarting computer ..." | ||||||
|  |             Restart-Computer -Force | ||||||
|  |         } | ||||||
|  |         elseif ($NotifyRestart) { | ||||||
|  |             Stop-Execution -ExitCode 3010 -ExitString "Please restart the computer now." | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  | } | ||||||
|  |  | ||||||
|  |  | ||||||
|  |  | ||||||
|  | Function Get-PasswordAsSecureString { | ||||||
|  | <# | ||||||
|  | .SYNOPSIS | ||||||
|  | Convert to / request password as secure string. | ||||||
|  | #> | ||||||
|  |     param ( | ||||||
|  |         [String] $Password, | ||||||
|  |         [String] $Prompt = "Please enter password" | ||||||
|  |     ) | ||||||
|  |      | ||||||
|  |     if ($Password -eq "") { | ||||||
|  |         Read-Host -Prompt $Prompt -AsSecureString | ||||||
|  |     } | ||||||
|  |     else { | ||||||
|  |         ConvertTo-SecureString -String "$Password" -AsPlainText -Force | ||||||
|  |     } | ||||||
|  | } | ||||||
|  |  | ||||||
|  |  | ||||||
|  |  | ||||||
|  | Function New-Credential { | ||||||
|  | <# | ||||||
|  | .SYNOPSIS | ||||||
|  | Create new creadential object with username and password provided. | ||||||
|  | #> | ||||||
|  | 	param ( | ||||||
|  | 		[Parameter(Mandatory=$true)] | ||||||
|  | 		[String] $UserName, | ||||||
|  | 		 | ||||||
|  | 		[String] $Password | ||||||
|  | 	) | ||||||
|  | 	 | ||||||
|  | 	$SecurePassword = Get-PasswordAsSecureString -Password "$Password" | ||||||
|  | 	New-Object System.Management.Automation.PSCredential( "$UserName", $SecurePassword ) | ||||||
|  | } | ||||||
|  |  | ||||||
|  |  | ||||||
|  |  | ||||||
|  | Function Join-Domain { | ||||||
|  | <# | ||||||
|  | .SYNOPSIS | ||||||
|  | Executes "Join domain" action. | ||||||
|  | #> | ||||||
|  | 	param ( | ||||||
|  | 		[String] $DomainName, | ||||||
|  | 		[String] $UserName, | ||||||
|  | 		[String] $Password, | ||||||
|  |         [Switch] $AllowRestart | ||||||
|  | 	) | ||||||
|  | 	 | ||||||
|  | 	$Credential = New-Credential -UserName "$DomainName\$UserName" -Password $Password | ||||||
|  |  | ||||||
|  | 	# Add the computer to the domain | ||||||
|  | 	if (Test-ComputerName -DomainName $DomainName) { | ||||||
|  | 		#Stop-Execution -Success -ExitString "Computer already joined to domain '$DomainName'" | ||||||
|  |         Write-LogWarning "Computer already joined to domain '$DomainName'" | ||||||
|  | 	} | ||||||
|  | 	else { | ||||||
|  | 		Write-Log "Joining computer to domain '$DomainName' ..." | ||||||
|  | 		 | ||||||
|  | 		Add-Computer -DomainName $DomainName -Credential $Credential -Force -ErrorAction Stop | ||||||
|  | 		 | ||||||
|  |         if ($AllowRestart) { | ||||||
|  |             Write-Log "Restarting computer ..." | ||||||
|  |             Restart-Computer -Force | ||||||
|  |         } | ||||||
|  |         else { | ||||||
|  | 		    #Stop-Execution -ExitCode 3010 -ExitString "Please restart the computer now." | ||||||
|  |             Write-Log "Please restart the computer now." | ||||||
|  |         } | ||||||
|  | 	} | ||||||
|  | } | ||||||
|  |  | ||||||
|  |  | ||||||
|  |  | ||||||
|  | Function Invoke-WMSettingsChange { | ||||||
|  |     if (-not ("win32.nativemethods" -as [type])) { | ||||||
|  |         # Import SendMessageTimeout from Win32 | ||||||
|  |         Add-Type -Namespace Win32 -Name NativeMethods -MemberDefinition @" | ||||||
|  | [DllImport("user32.dll", SetLastError = true, CharSet = CharSet.Auto)] | ||||||
|  | public static extern IntPtr SendMessageTimeout( | ||||||
|  |     IntPtr hWnd, uint Msg, UIntPtr wParam, string lParam, | ||||||
|  |     uint fuFlags, uint uTimeout, out UIntPtr lpdwResult); | ||||||
|  | "@ | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     $HWND_BROADCAST = [IntPtr]0xFFFF | ||||||
|  |     $WM_SETTINGCHANGE = 0x001A | ||||||
|  |     $result = [UIntPtr]::Zero | ||||||
|  |  | ||||||
|  |     # Notify all windows of environment block change | ||||||
|  |     Write-Log "Executing 'SendMessageTimeout' ..." | ||||||
|  |  | ||||||
|  |     $retval = [Win32.NativeMethods]::SendMessageTimeout($HWND_BROADCAST, $WM_SETTINGCHANGE, | ||||||
|  | 	    [UIntPtr]::Zero, "Environment", 2, 5000, [ref] $result) | ||||||
|  |      | ||||||
|  |     Write-Log "'SendMessageTimeout' returned '$retval' (non-zero is OK)" | ||||||
|  | } | ||||||
|  |  | ||||||
|  |  | ||||||
|  |  | ||||||
|  | Function Set-AutoLogonCredentials { | ||||||
|  | 	param ( | ||||||
|  | 		[String] $DomainName, | ||||||
|  | 		[String] $UserName, | ||||||
|  | 		[String] $Password | ||||||
|  | 	) | ||||||
|  | 	 | ||||||
|  | 	$KeyName = "HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Winlogon" | ||||||
|  |  | ||||||
|  | 	if ($DomainName -ne "") { | ||||||
|  | 		$UserName = "$DomainName\$UserName" | ||||||
|  | 	} | ||||||
|  |      | ||||||
|  |     Write-Log "Setting AutoLogon credentials ..." | ||||||
|  | 	try { | ||||||
|  |     	[Microsoft.Win32.Registry]::SetValue($KeyName, "DefaultUserName", "$UserName", [Microsoft.Win32.RegistryValueKind]::String) | ||||||
|  |     	[Microsoft.Win32.Registry]::SetValue($KeyName, "DefaultPassword", "$Password", [Microsoft.Win32.RegistryValueKind]::String) | ||||||
|  |     	[Microsoft.Win32.Registry]::SetValue($KeyName, "AutoAdminLogon", "1", [Microsoft.Win32.RegistryValueKind]::String) | ||||||
|  |     	[Microsoft.Win32.Registry]::SetValue($KeyName, "ForceAutoLogon", "1", [Microsoft.Win32.RegistryValueKind]::String) | ||||||
|  |     } | ||||||
|  |     catch { | ||||||
|  |         Write-LogError "FAILED" | ||||||
|  |         return | ||||||
|  |     } | ||||||
|  |      | ||||||
|  |     Write-Log "SUCCESS" | ||||||
|  | } | ||||||
|  |  | ||||||
|  |  | ||||||
|  |  | ||||||
|  | Function Start-Program { | ||||||
|  | 	param ( | ||||||
|  | 		[String] $FilePath, | ||||||
|  | 		[String[]] $ArgumentList = @(' '), | ||||||
|  | 		[Int] $Timeout = 0, | ||||||
|  | 		[Switch] $NoWait, | ||||||
|  | 		[Switch] $PassThru | ||||||
|  | 	) | ||||||
|  |  | ||||||
|  | 	trap { | ||||||
|  | 		Write-LogError $_.Exception.Message | ||||||
|  | 		return $null | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	Write-Log "Starting program: $FilePath $ArgumentList" | ||||||
|  | 		 | ||||||
|  | 	$ProcessStartInfo = New-Object System.Diagnostics.ProcessStartInfo | ||||||
|  | 	$ProcessStartInfo.FileName = $FilePath | ||||||
|  | 	$ProcessStartInfo.Arguments = $ArgumentList | ||||||
|  | 	$ProcessStartInfo.CreateNoWindow = $true | ||||||
|  | 	$ProcessStartInfo.RedirectStandardOutput = $true | ||||||
|  | 	$ProcessStartInfo.RedirectStandardError = $true | ||||||
|  | 	$ProcessStartInfo.UseShellExecute = $false | ||||||
|  | 		 | ||||||
|  | 	$Process = [System.Diagnostics.Process]::Start($ProcessStartInfo) | ||||||
|  | 		 | ||||||
|  | 	if ($NoWait) { | ||||||
|  | 		if ($PassThru) { | ||||||
|  | 			return $Process | ||||||
|  | 		} | ||||||
|  | 		else { | ||||||
|  | 			return $null | ||||||
|  | 		} | ||||||
|  | 	} | ||||||
|  | 	else { | ||||||
|  | 		if ($Timeout -eq 0) { | ||||||
|  | 			$Process.WaitForExit() | ||||||
|  | 		} | ||||||
|  | 		else { | ||||||
|  | 			$Process.WaitForExit($Timeout) | ||||||
|  | 		} | ||||||
|  | 	} | ||||||
|  | 		 | ||||||
|  | 	Write-Log ( "STDOUT:`n{0}" -f $Process.StandardOutput.ReadToEnd() ) | ||||||
|  |     Write-Log ":STDOUT" | ||||||
|  | 		 | ||||||
|  | 	Write-Log ( "STDERR:`n{0}" -f $Process.StandardError.ReadToEnd() ) | ||||||
|  |     Write-Log ":STDERR" | ||||||
|  | 		 | ||||||
|  | 	Write-Log "Program has finished with exit code ($($Process.ExitCode))" | ||||||
|  |  | ||||||
|  | 	if ($PassThru) { | ||||||
|  | 		return $Process | ||||||
|  | 	} | ||||||
|  | 	else { | ||||||
|  | 		return $null | ||||||
|  | 	} | ||||||
|  | } | ||||||
|  | New-Alias -Name Exec -Value Start-Program | ||||||
|  |  | ||||||
|  |  | ||||||
|  |  | ||||||
|  | function Test-ModuleVersion { | ||||||
|  | <# | ||||||
|  | .SYNOPSIS | ||||||
|  | Test module version. | ||||||
|  |  | ||||||
|  | .DESCRIPTION | ||||||
|  | Function specified module (current module by default), and compares it's version to version provided. | ||||||
|  | Returned values: | ||||||
|  | * -2 : error occured | ||||||
|  | * -1 : module's version is lower than one provided | ||||||
|  | *  0 : module's version is equal to one provided | ||||||
|  | *  1 : module's version is greater than one provided | ||||||
|  | #> | ||||||
|  |     param ( | ||||||
|  |         [String] $Name = "$__ModuleName", | ||||||
|  |         [String] $Version | ||||||
|  |     ) | ||||||
|  |  | ||||||
|  |     $ModuleVersion = (Get-Module -Name $Name -ListAvailable).Version | ||||||
|  |      | ||||||
|  |     if ($ModuleVersion -eq $null) { | ||||||
|  |         Write-Log "Module '$Name' not found." | ||||||
|  |         return -2 | ||||||
|  |     } | ||||||
|  |      | ||||||
|  |     try { | ||||||
|  |         $RequiredVersion = [System.Version]::Parse($Version) | ||||||
|  |     } | ||||||
|  |     catch { | ||||||
|  |         Write-Log "'$Version' is not a correct version string." | ||||||
|  |         return -2 | ||||||
|  |     } | ||||||
|  |      | ||||||
|  |     $ModuleVersion.CompareTo($RequiredVersion) | ||||||
|  | } | ||||||
|  |  | ||||||
|  |  | ||||||
|  |  | ||||||
|  | Function Set-LocalUserPassword { | ||||||
|  |     param ( | ||||||
|  |         [String] $UserName, | ||||||
|  |         [String] $Password, | ||||||
|  |         [Switch] $Force | ||||||
|  |     ) | ||||||
|  |      | ||||||
|  |     trap { Stop-Execution $_ } | ||||||
|  |      | ||||||
|  |     if ((Get-WmiObject Win32_UserAccount -Filter "LocalAccount = 'True' AND Name='$UserName'") -eq $null) { | ||||||
|  |         throw "Unable to find local user account '$UserName'" | ||||||
|  |     } | ||||||
|  |      | ||||||
|  |     if ($Force) { | ||||||
|  |         Write-Log "Changing password for user '$UserName' to '*****'" # :) | ||||||
|  |         ([ADSI] "WinNT://./$UserName").SetPassword($Password) | Out-Null | ||||||
|  |     } | ||||||
|  |     else { | ||||||
|  |         Write-LogWarning "You are trying to change the password for the user '$UserName'. To do this please run the command again with -Force parameter." | ||||||
|  |     } | ||||||
|  | } | ||||||
|  |  | ||||||
|  |  | ||||||
|  |  | ||||||
|  | Function Resolve-LdapDnsName { | ||||||
|  |     param ( | ||||||
|  |         [String] $DomainName | ||||||
|  |     ) | ||||||
|  |      | ||||||
|  |     Resolve-DNSName -Type "SRV" -Name "_ldap._tcp.dc._msdcs.$DomainName" | | ||||||
|  |         Where-Object { $_.Type -eq "A" } | | ||||||
|  |         Select-Object -Property Name,IPAddress | ||||||
|  | } | ||||||
|  |  | ||||||
|  |  | ||||||
|  |  | ||||||
|  | Function Wait-LdapServerAvailable { | ||||||
|  |     param ( | ||||||
|  |         [String] $DomainName, | ||||||
|  |         [Int] $PingSeqCountThreshold = 10, | ||||||
|  |         [Int] $PingSeqPerHostThreshold = 5 | ||||||
|  |     ) | ||||||
|  |      | ||||||
|  |     $LdapServerList = @( Resolve-LdapDnsName $DomainName ) | ||||||
|  |     Write-Log @( "Ldap server list:", ( $LdapServerList | Out-String ) ) | ||||||
|  |      | ||||||
|  |     :MainLoop foreach ($LdapServer in $LdapServerList) { | ||||||
|  |         $PingSeqCount = 0 | ||||||
|  |         $PingSeqPerHost = 0 | ||||||
|  |         while ($PingSeqPerHost -lt $PingSeqPerHostThreshold) { | ||||||
|  |             if (Test-Connection -ComputerName $LdapServer.IpAddress -Count 1 -Quiet) { | ||||||
|  |                 Write-Log "Ping '$($LdapServer.Name)' OK" | ||||||
|  |                 $PingSeqCount++ | ||||||
|  |             } | ||||||
|  |             else { | ||||||
|  |                 Write-Log "Ping '$($LdapServer.Name)' FAILED" | ||||||
|  |                 $PingSeqCount = 0 | ||||||
|  |                 $PingSeqPerHost++ | ||||||
|  |             } | ||||||
|  |              | ||||||
|  |             if ($PingSeqCount -ge $PingSeqCountThreshold) { | ||||||
|  |                 Write-Log "Returning true" | ||||||
|  |                 return $true | ||||||
|  |             } | ||||||
|  |              | ||||||
|  |             Start-Sleep -Seconds 1 | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  |      | ||||||
|  |     Write-Log "Returning false" | ||||||
|  |     return $false | ||||||
|  | } | ||||||
|  |  | ||||||
|  |  | ||||||
| @@ -0,0 +1,139 @@ | |||||||
|  | Function Initialize-Logger { | ||||||
|  |     param ( | ||||||
|  |         [String] $ModuleName = $__ModuleName, | ||||||
|  |         [String] $LogPath = $__DefaultLogPath | ||||||
|  |     ) | ||||||
|  |      | ||||||
|  |     if (-not ("log4net.LogManager" -as [type])) { | ||||||
|  |         $FileStream = ([System.IO.FileInfo] (Get-Item "$__ModulePath\log4net.dll")).OpenRead() | ||||||
|  |  | ||||||
|  |         $AssemblyBytes = New-Object Byte[] $FileStream.Length | ||||||
|  |         [Void] $FileStream.Read($AssemblyBytes, 0, $FileStream.Length) | ||||||
|  |  | ||||||
|  |         $FileStream.Close() | ||||||
|  |  | ||||||
|  |         [Void] [System.Reflection.Assembly]::Load($AssemblyBytes) | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     [log4net.GlobalContext]::Properties["LogPath"] = $LogPath | ||||||
|  |     [log4net.GlobalContext]::Properties["ModuleName"] = $ModuleName | ||||||
|  |  | ||||||
|  |     $script:__Logger = [log4net.LogManager]::GetLogger("PowerShell") | ||||||
|  |  | ||||||
|  |     $Log4NetConfig = New-Object System.IO.FileInfo("$__ModulePath\log4net.config") | ||||||
|  |  | ||||||
|  |     [log4net.Config.XmlConfigurator]::Configure($Log4NetConfig) | ||||||
|  |      | ||||||
|  |     $__Logger.info("Logger initialized. Log file: '$LogPath'") | ||||||
|  | } | ||||||
|  |  | ||||||
|  |  | ||||||
|  |  | ||||||
|  | Function Write-LogInfo { | ||||||
|  | 	param ( | ||||||
|  | 		[String[]] $Text | ||||||
|  | 	) | ||||||
|  |     foreach ($Line in $Text) { | ||||||
|  |         $__Logger.info($Line) | ||||||
|  |     } | ||||||
|  | } | ||||||
|  | New-Alias -Name Write-Log -Value Write-LogInfo | ||||||
|  |  | ||||||
|  |  | ||||||
|  |  | ||||||
|  | Function Out-LogInfo { | ||||||
|  | 	param ( | ||||||
|  | 		[Parameter(ValueFromPipeline=$true)] | ||||||
|  | 		[String] $Text | ||||||
|  | 	) | ||||||
|  | 	$__Logger.info($Text) | ||||||
|  | } | ||||||
|  | New-Alias -Name Out-Log -Value Out-LogInfo | ||||||
|  |  | ||||||
|  |  | ||||||
|  |  | ||||||
|  | Function Write-LogWarning { | ||||||
|  | 	param ( | ||||||
|  | 		[String] $Text | ||||||
|  | 	) | ||||||
|  |     foreach ($Line in $Text) { | ||||||
|  | 	    $__Logger.warn($Line) | ||||||
|  |     } | ||||||
|  | } | ||||||
|  |  | ||||||
|  |  | ||||||
|  |  | ||||||
|  | Function Out-LogWarning { | ||||||
|  | 	param ( | ||||||
|  | 		[Parameter(ValueFromPipeline=$true)] | ||||||
|  | 		[String] $Text | ||||||
|  | 	) | ||||||
|  | 	$__Logger__.warn($Text) | ||||||
|  | } | ||||||
|  |  | ||||||
|  |  | ||||||
|  |  | ||||||
|  | Function Write-LogError { | ||||||
|  | 	param ( | ||||||
|  | 		[String] $Text | ||||||
|  | 	) | ||||||
|  |     foreach ($Line in $Text) { | ||||||
|  | 	    $__Logger.error($Line) | ||||||
|  |     } | ||||||
|  | } | ||||||
|  |  | ||||||
|  |  | ||||||
|  |  | ||||||
|  | Function Out-LogError { | ||||||
|  | 	param ( | ||||||
|  | 		[Parameter(ValueFromPipeline=$true)] | ||||||
|  | 		[String] $Text | ||||||
|  | 	) | ||||||
|  | 	$__Logger.error($Text) | ||||||
|  | } | ||||||
|  |  | ||||||
|  |  | ||||||
|  |  | ||||||
|  | Function Write-LogFatal { | ||||||
|  | 	param ( | ||||||
|  | 		[String] $Text | ||||||
|  | 	) | ||||||
|  |     foreach ($Line in $Text) { | ||||||
|  | 	    $__Logger.fatal($Line) | ||||||
|  |     } | ||||||
|  | } | ||||||
|  |  | ||||||
|  |  | ||||||
|  |  | ||||||
|  | Function Out-LogFatal { | ||||||
|  | 	param ( | ||||||
|  | 		[Parameter(ValueFromPipeline=$true)] | ||||||
|  | 		[String] $Text | ||||||
|  | 	) | ||||||
|  | 	$__Logger.fatal($Text) | ||||||
|  | } | ||||||
|  |  | ||||||
|  |  | ||||||
|  |  | ||||||
|  | Function Write-LogDebug { | ||||||
|  | 	param ( | ||||||
|  | 		[String] $Text | ||||||
|  | 	) | ||||||
|  |     foreach ($Line in $Text) { | ||||||
|  | 	    $__Logger.debug($Line) | ||||||
|  |     } | ||||||
|  | } | ||||||
|  |  | ||||||
|  |  | ||||||
|  |  | ||||||
|  | Function Out-LogDebug { | ||||||
|  | 	param ( | ||||||
|  | 		[Parameter(ValueFromPipeline=$true)] | ||||||
|  | 		[String] $Text | ||||||
|  | 	) | ||||||
|  | 	$__Logger.debug($Text) | ||||||
|  | } | ||||||
|  |  | ||||||
|  |  | ||||||
|  |  | ||||||
|  | Initialize-Logger | ||||||
| @@ -0,0 +1,172 @@ | |||||||
|  | Function Get-ModuleHelp { | ||||||
|  |     param ( | ||||||
|  |         [String] $ModuleName = $__ModuleName, | ||||||
|  |         [String] $Path = "", | ||||||
|  |         [Switch] $File, | ||||||
|  |         [Int] $Width = 80 | ||||||
|  |     ) | ||||||
|  |      | ||||||
|  | 	$sb = { | ||||||
|  |         $Module = Get-Module $ModuleName | ||||||
|  |     	 | ||||||
|  |     	"`n" | ||||||
|  |         "Module: $($Module.Name)" | ||||||
|  |     	"Module version: $($Module.Version)" | ||||||
|  |     	"`n" | ||||||
|  |         "{0} Module Description {0}" -f ('=' * 30) | ||||||
|  |         "`n" | ||||||
|  |          | ||||||
|  |     	Get-Help "about_$($Module.Name)" | Out-String -Width $Width | ||||||
|  |     	 | ||||||
|  |         "{0} Exported Functions {0}" -f ('=' * 30) | ||||||
|  |         "`n" | ||||||
|  |         	 | ||||||
|  |     	foreach ($CommandName in $Module.ExportedCommands.Keys) { | ||||||
|  |             '-' * 80 | ||||||
|  |     		Get-Help -Name $CommandName -Detailed | Out-String -Width $Width | ||||||
|  |     	} | ||||||
|  |     } | ||||||
|  |      | ||||||
|  |     if (($File) -and ($Path -eq "")) { | ||||||
|  |         $Path = [IO.Path]::GetTempFileName() | ||||||
|  |     } | ||||||
|  |      | ||||||
|  |     if ($Path -ne "") { | ||||||
|  |         & $sb | Out-File -FilePath $Path -Force | ||||||
|  |     } | ||||||
|  |     else { | ||||||
|  |         & $sb | Out-Default | ||||||
|  |     } | ||||||
|  |      | ||||||
|  |     if ($File) { | ||||||
|  |         notepad.exe "$Path" | ||||||
|  |     } | ||||||
|  | } | ||||||
|  |  | ||||||
|  |  | ||||||
|  |  | ||||||
|  | function Update-PsModulePath { | ||||||
|  |     param ( | ||||||
|  |         [String] $AddPath = "" | ||||||
|  |     ) | ||||||
|  |  | ||||||
|  |     $NewPsModulePath = ( | ||||||
|  |             @([Environment]::GetEnvironmentVariable("PsModulePath", [EnvironmentVariableTarget]::Machine) -split ";") + @($AddPath) ` | ||||||
|  |             | Select-Object -Unique | ||||||
|  |         ) -join ';' | ||||||
|  |      | ||||||
|  |     [Environment]::SetEnvironmentVariable("PsModulePath", $NewPsModulePath, [EnvironmentVariableTarget]::Machine) | ||||||
|  |      | ||||||
|  |     Invoke-WMSettingsChange | ||||||
|  | } | ||||||
|  |  | ||||||
|  |  | ||||||
|  |  | ||||||
|  | Function Install-Module { | ||||||
|  |     param ( | ||||||
|  |         [String] $InstallPath, | ||||||
|  |         [String] $ModulePath, | ||||||
|  |         [String] $ModuleName | ||||||
|  |     ) | ||||||
|  |  | ||||||
|  |     if ($ModuleName -eq "") { | ||||||
|  |         if ($ModulePath -eq "") { | ||||||
|  |             Stop-Execution -ExitString "Don't know which module should be installed." | ||||||
|  |         } | ||||||
|  |         else { | ||||||
|  |              $ModuleName = $ModulePath.Split("\")[-1] | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  |      | ||||||
|  |     if ($InstallPath -eq "") { | ||||||
|  |         Stop-Execution -ExitString "To install the module destination path must be provided." | ||||||
|  |     } | ||||||
|  |     else { | ||||||
|  |         Write-Log "Installing the module to '$InstallPath'" | ||||||
|  |          | ||||||
|  |         $NewModulePath = [IO.Path]::Combine($InstallPath, $ModuleName) | ||||||
|  |         if ([IO.Directory]::Exists($NewModulePath)) { | ||||||
|  |             [IO.Directory]::Delete($NewModulePath, $true) | ||||||
|  |         } | ||||||
|  |              | ||||||
|  |         Copy-Item -Path $ModulePath -Destination $InstallPath -Recurse -Force -ErrorAction Stop | ||||||
|  |              | ||||||
|  |         Update-PsModulePath -AddPath "$InstallPath" | ||||||
|  |     } | ||||||
|  | } | ||||||
|  |  | ||||||
|  |  | ||||||
|  |  | ||||||
|  | Function Register-Module { | ||||||
|  |     param ( | ||||||
|  |         [String] $ModulePath | ||||||
|  |     ) | ||||||
|  |     $ModuleRoot = Split-Path -Path $ModulePath -Parent | ||||||
|  |     Write-Log "Registering the module at '$ModuleRoot'" | ||||||
|  |     Update-PsModulePath -AddPath "$ModuleRoot" | ||||||
|  | } | ||||||
|  |  | ||||||
|  |  | ||||||
|  |  | ||||||
|  | Function New-ModuleTemplate { | ||||||
|  |     param ( | ||||||
|  |         [Parameter(Mandatory=$true)] | ||||||
|  |         [String] $Name, | ||||||
|  |          | ||||||
|  |         [String] $Path = "$($Env:USERPROFILE)\Documents\WindowsPowerShell\Modules", | ||||||
|  |          | ||||||
|  |         [Switch] $Force | ||||||
|  |     ) | ||||||
|  |     if ([IO.Directory]::Exists("$Path\$Name")) { | ||||||
|  |         if ($Force) { | ||||||
|  |             [IO.Directory]::Delete("$Path\$Name", $true) | ||||||
|  |         } | ||||||
|  |         else { | ||||||
|  |             Write-Error "Folder '$Path\$Name' already exists. Remove it manually or specify -Force switch." | ||||||
|  |             return | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  |      | ||||||
|  |      | ||||||
|  |     [IO.Directory]::CreateDirectory("$Path\$Name") | ||||||
|  |     [IO.Directory]::CreateDirectory("$Path\$Name\en-US") | ||||||
|  |     [IO.Directory]::CreateDirectory("$Path\$Name\include") | ||||||
|  |      | ||||||
|  |      | ||||||
|  |     Set-Content -Path "$Path\$Name\en-US\about_$Name.help.txt" -Value @' | ||||||
|  | '@ | ||||||
|  |  | ||||||
|  |      | ||||||
|  |     Set-Content -Path "$Path\$Name\Config.ps1" -Value @' | ||||||
|  | $script:__ModulePath = $PsScriptRoot | ||||||
|  | $script:__ModuleName = $PsScriptRoot.Split("\")[-1] | ||||||
|  | $script:__DefaultLogPath = [IO.Path]::Combine([IO.Path]::GetTempPath(), "PowerShell_$__ModuleName.log") | ||||||
|  |  | ||||||
|  | $global:__StopExecutionExitsSession__ = $false | ||||||
|  | '@     | ||||||
|  |      | ||||||
|  |      | ||||||
|  |     Set-Content -Path "$Path\$Name\$Name.psm1" -Value @' | ||||||
|  | # Import config first | ||||||
|  | . "$PsScriptRoot\Config.ps1" | ||||||
|  |  | ||||||
|  | # Import functions from 'Include' subfolder | ||||||
|  | Get-ChildItem "$PsScriptRoot\Include" -Filter "*.ps1" | | ||||||
|  |     ForEach-Object { | ||||||
|  |         . "$($_.FullName)" | ||||||
|  |     } | ||||||
|  |  | ||||||
|  | Export-ModuleMember -Function * -Alias * | ||||||
|  |  | ||||||
|  | Initialize-Logger -ModuleName $__ModuleName -LogPath $__DefaultLogPath | ||||||
|  |  | ||||||
|  | Write-Log "Module loaded from '$PsScriptRoot'" | ||||||
|  | '@ | ||||||
|  |      | ||||||
|  |      | ||||||
|  |     New-ModuleManifest ` | ||||||
|  |         -Path "$Path\$Name\$Name.psd1" ` | ||||||
|  |         -ModuleToProcess "$Name.psm1" ` | ||||||
|  |         -RequiredModules "CoreFunctions" | ||||||
|  |      | ||||||
|  | } | ||||||
| @@ -0,0 +1,120 @@ | |||||||
|  | function New-SqlServerConnection { | ||||||
|  |     param ( | ||||||
|  |         [String] $ServerName, | ||||||
|  |         [String] $UserName = '', | ||||||
|  |         [String] $Password = '', | ||||||
|  |         $Credentials, | ||||||
|  |         [Switch] $SqlAuth | ||||||
|  |     ) | ||||||
|  |  | ||||||
|  |     if ($Credentials -eq $null) { | ||||||
|  |         if ($UserName -eq '') { | ||||||
|  |             throw "User name must be provided in order to create credentials object!" | ||||||
|  |         } | ||||||
|  |          | ||||||
|  |         $Credentials = New-Credential -UserName $UserName -Password $Password | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     $Server = New-Object ` | ||||||
|  |         -TypeName Microsoft.SqlServer.Management.Smo.Server ` | ||||||
|  |         -ArgumentList $ServerName | ||||||
|  |      | ||||||
|  |     $LoginName = $Credentials.UserName -replace("^\\", "") | ||||||
|  |  | ||||||
|  |     try { | ||||||
|  |         if ($SqlAuth) { | ||||||
|  |             $Server.ConnectionContext.set_LoginSecure($false) | ||||||
|  |             $Server.ConnectionContext.set_Login($LoginName) | ||||||
|  |             $Server.ConnectionContext.set_SecurePassword($Credentials.Password) | ||||||
|  |         } | ||||||
|  |         else { | ||||||
|  |             throw "Not implemented!" | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  |     catch { | ||||||
|  |         return $null | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     $Server | ||||||
|  | } | ||||||
|  |  | ||||||
|  |  | ||||||
|  |  | ||||||
|  | function Import-SqlServerAssemblies { | ||||||
|  | <# | ||||||
|  | .SYNOPSIS | ||||||
|  | Import assemblies required to work with Sql Server instance from PowerShell | ||||||
|  |  | ||||||
|  | .DESCRIPTION | ||||||
|  | Possible assembly list: | ||||||
|  |     "Microsoft.SqlServer.Management.Common" | ||||||
|  |     "Microsoft.SqlServer.Smo" | ||||||
|  |     "Microsoft.SqlServer.Dmf" | ||||||
|  |     "Microsoft.SqlServer.Instapi" | ||||||
|  |     "Microsoft.SqlServer.SqlWmiManagement" | ||||||
|  |     "Microsoft.SqlServer.ConnectionInfo" | ||||||
|  |     "Microsoft.SqlServer.SmoExtended" | ||||||
|  |     "Microsoft.SqlServer.SqlTDiagM" | ||||||
|  |     "Microsoft.SqlServer.SString" | ||||||
|  |     "Microsoft.SqlServer.Management.RegisteredServers" | ||||||
|  |     "Microsoft.SqlServer.Management.Sdk.Sfc" | ||||||
|  |     "Microsoft.SqlServer.SqlEnum" | ||||||
|  |     "Microsoft.SqlServer.RegSvrEnum" | ||||||
|  |     "Microsoft.SqlServer.WmiEnum" | ||||||
|  |     "Microsoft.SqlServer.ServiceBrokerEnum" | ||||||
|  |     "Microsoft.SqlServer.ConnectionInfoExtended" | ||||||
|  |     "Microsoft.SqlServer.Management.Collector" | ||||||
|  |     "Microsoft.SqlServer.Management.CollectorEnum" | ||||||
|  |     "Microsoft.SqlServer.Management.Dac" | ||||||
|  |     "Microsoft.SqlServer.Management.DacEnum" | ||||||
|  |     "Microsoft.SqlServer.Management.Utility" | ||||||
|  |  | ||||||
|  | .LINKS | ||||||
|  | http://msdn.microsoft.com/en-us/library/cc281962%28v=sql.105%29.aspx | ||||||
|  | #> | ||||||
|  |     $AssemblyList = @( | ||||||
|  |         "Microsoft.SqlServer.Smo" | ||||||
|  |         "Microsoft.SqlServer.SmoExtended" | ||||||
|  |     ) | ||||||
|  |          | ||||||
|  |     foreach ($asm in $AssemblyList) { | ||||||
|  |         [System.Reflection.Assembly]::LoadWithPartialName($asm) | Out-Null | ||||||
|  |     } | ||||||
|  | } | ||||||
|  |  | ||||||
|  |  | ||||||
|  |  | ||||||
|  | function Import-SqlServerProvider { | ||||||
|  |     $SqlPsReg="HKLM:\SOFTWARE\Microsoft\PowerShell\1\ShellIds\Microsoft.SqlServer.Management.PowerShell.sqlps" | ||||||
|  |  | ||||||
|  |     if (Get-ChildItem $SqlPsReg -ErrorAction "SilentlyContinue") { | ||||||
|  |         throw "SQL Server Provider for Windows PowerShell is not installed." | ||||||
|  |     } | ||||||
|  |     else { | ||||||
|  |         $Item = Get-ItemProperty $SqlPsReg | ||||||
|  |         $SqlPsPath = [System.IO.Path]::GetDirectoryName($Item.Path) | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     # | ||||||
|  |     # Set mandatory variables for the SQL Server provider | ||||||
|  |     # | ||||||
|  |     $global:SqlServerMaximumChildItems = 0 | ||||||
|  |     $global:SqlServerConnectionTimeout = 30 | ||||||
|  |     $global:SqlServerIncludeSystemObjects = $false | ||||||
|  |     $global:SqlServerMaximumTabCompletion = 1000 | ||||||
|  |  | ||||||
|  |     # | ||||||
|  |     # Load the snapins, type data, format data | ||||||
|  |     # | ||||||
|  |     Push-Location | ||||||
|  |     Set-Location $sqlpsPath | ||||||
|  |      | ||||||
|  |     Add-PSSnapin SqlServerCmdletSnapin100 | ||||||
|  |     Add-PSSnapin SqlServerProviderSnapin100 | ||||||
|  |      | ||||||
|  |     Update-TypeData -PrependPath SQLProvider.Types.ps1xml  | ||||||
|  |     Update-FormatData -PrependPath SQLProvider.Format.ps1xml  | ||||||
|  |      | ||||||
|  |     Pop-Location | ||||||
|  | } | ||||||
|  |  | ||||||
| @@ -0,0 +1,42 @@ | |||||||
|  | <log4net> | ||||||
|  |         <appender name="RollingFileAppender" type="log4net.Appender.RollingFileAppender" > | ||||||
|  |             <param name="File" type="log4net.Util.PatternString" value="%property{LogPath}" /> | ||||||
|  |             <param name="AppendToFile" value="true" /> | ||||||
|  |             <param name="RollingStyle" value="Size" /> | ||||||
|  |             <param name="MaxSizeRollBackups" value="100" /> | ||||||
|  |             <param name="MaximumFileSize" value="1024KB" /> | ||||||
|  |             <param name="StaticLogFileName" value="true" /> | ||||||
|  |             <lockingModel type="log4net.Appender.FileAppender+MinimalLock" /> | ||||||
|  |             <layout type="log4net.Layout.PatternLayout">                | ||||||
|  |                 <param name="ConversionPattern" value="%date [%-5level] [%property{ModuleName}] %message%newline" /> | ||||||
|  |             </layout> | ||||||
|  |         </appender> | ||||||
|  | 		 | ||||||
|  | 		<appender name="ColoredConsoleAppender" type="log4net.Appender.ColoredConsoleAppender"> | ||||||
|  | 			<mapping> | ||||||
|  | 				<level value="error" /> | ||||||
|  | 				<foreColor value="Red, HighIntensity" /> | ||||||
|  | 			</mapping> | ||||||
|  | 			<mapping> | ||||||
|  | 				<level value="warn" /> | ||||||
|  | 				<foreColor value="Yellow, HighIntensity" /> | ||||||
|  | 			</mapping> | ||||||
|  | 			<mapping> | ||||||
|  | 				<level value="info" /> | ||||||
|  | 				<foreColor value="Green, HighIntensity" /> | ||||||
|  | 			</mapping> | ||||||
|  | 			<layout type="log4net.Layout.PatternLayout"> | ||||||
|  | 				<conversionPattern value="%date [%-5level] [%property{ModuleName}] %message%newline" /> | ||||||
|  | 			</layout> | ||||||
|  | 		</appender> | ||||||
|  |  | ||||||
|  |         <!--root> | ||||||
|  |             <level value="info" />             | ||||||
|  |         </root--> | ||||||
|  |  | ||||||
|  |      <logger name="PowerShell" additivity="false"> | ||||||
|  |         <!--level value="info" /--> | ||||||
|  |         <appender-ref ref="ColoredConsoleAppender" /> | ||||||
|  | 		<appender-ref ref="RollingFileAppender" /> | ||||||
|  |      </logger> | ||||||
|  | </log4net> | ||||||
							
								
								
									
										
											BIN
										
									
								
								Deployment/WindowsPowerShell/Modules/CoreFunctions/log4net.dll
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										
											BIN
										
									
								
								Deployment/WindowsPowerShell/Modules/CoreFunctions/log4net.dll
									
									
									
									
									
										Normal file
									
								
							
										
											Binary file not shown.
										
									
								
							
		Reference in New Issue
	
	Block a user
	 Dmitry Teselkin
					Dmitry Teselkin