Windows PowerShell module added
This commit is contained in:
parent
779e61ba72
commit
f76f434648
@ -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.
Loading…
x
Reference in New Issue
Block a user