Disable proxy settings at system level

Today I was facing some issues with the proxy server at the company I was working for.
It seemed that a rule was applied that made all servers connect outbound trough a proxy, instead of only the desktops as provided.

In an attempt to quickly resolve this issue, I quickly searched the internet.
I found that its rather easy to find how to disable the proxy settings using GPO, or at a user level. However it was not that easy to find how to disable this at a system level.

It seems that there are 2 registry keys that need to be created (or modified) to do this.
These registry keys are located at HKLM:\SOFTWARE\Policies\Microsoft\Windows\CurrentVersion\Internet Settings

Step 1, disable the user based proxy settings:
In the HKLM:\SOFTWARE\Policies\Microsoft\Windows\CurrentVersion\Internet Settings there is a DWORD called ProxySettingsPerUser, if this is set to 0 it will be disabled and system wide settings are used. Put it back to 1 or remove this key entirely to enable user based proxy settings again.

Step 2, disable the automatic detect proxy settings checkbox.
In the HKLM:\SOFTWARE\Policies\Microsoft\Windows\CurrentVersion\Internet Settings there is a DWORD called EnableAutoProxyResultCache, set it to 0 and it will be disabled.

Here is a simple script you can use to inject these settings into the registry directly.

$regPath = "HKLM:\SOFTWARE\Policies\Microsoft\Windows\CurrentVersion\Internet Settings"
$null = New-ItemProperty -Path $regPath -Name 'ProxySettingsPerUser' -Value 0 -PropertyType DWORD -Force
$null = New-ItemProperty -Path $regPath -Name 'EnableAutoProxyResultCache' -Value 0 -PropertyType DWORD -Force

~Danny

New SQLServer DSC Resource cSQLServer

Today we have released a new SQL Server DSC Resource that has been created by merging the already existing xSQLServer and xSqlPs resources and adding new functionality like:

– SQL Always-On (with domain credentials)
– SQL Always-On between 2 Clusters
– SQL File streaming
– SQL Always-On with Listener

For more information please check the source at:

cSQLServer:       https://github.com/Solvinity/cSQLServer
cFailoverCluster: https://github.com/Solvinity/cFailoverCluster
Demo Video:       https://youtu.be/l8KwLUtXNB8

A more in depth article will be published early January!

-Danny

Activate Windows VMs using Powershell Direct

# This code requires Windows 10 professional/Enterprise or Windows Server 2016
$vmname = read-host "VMName"
$key = read-host "Windows Key"
 
Invoke-Command -VMName $vmname -ScriptBlock {
param($key)
Write-Verbose -Message "Attempting to inject Windows key: $key"
Cscript.exe $env:SystemRoot\System32\slmgr.vbs -ipk $key
Write-Verbose -Message "Attempting to activate Windows key"
Cscript.exe $env:SystemRoot\System32\slmgr.vbs -ato
} -ArgumentList $key

 

DSC Module: cManageCertificates

I just bumped into the issue where I needed to import a certificate to a server before I could use it in a DSC resource. Since there was no DSC Resource available yet to import or remove certificates from a certain store from a computer I had to create one myself.

cManageCertificates

The result can be found here: https://github.com/DdenBraver/cManageCertificates

This resource is pretty simple, and it uses the powershell cmdlet Import-PfxCertificate to import a certificate, and the Remove-Item “Cert:\Storetype\Store\Thumbprint” to remove a certificate if required.

Using Powershell Packagemanager (OneGet) basics

One of the new great features of WMF5, included in Windows 10 RTM is Powershell Packagemanager (previously called OneGet).

I will not go into the details on how it works or what it is (that you can find here!) I do want to show you how you can use it to simply install some packages from the powershell gallery, or from chocolatey which is basically a community based package source that already includes alot of applications and tools.

Lets take a look at the basic command sets:
Find-Package: find the package you are looking for in the registered package sources in powershell packagemanager
Get-Package: finds the packages on your system that have been installed using powershell packagemanager
Install-Package: installs a package on your system using powershell packagemanager
Uninstall-Package: removes a package from your system that was installed using powershell packagemanager

When you first kick off find-package you may get the request that the package provider nuget has not been installed and needs to be downloaded and installed.

The provider 'nuget v2.8.5.127' is not installed.
nuget may be manually downloaded from https://oneget.org/nuget-anycpu-2.8.5.127.exe and installed.
Would you like PackageManagement to automatically download and install 'nuget' now?
[Y] Yes  [N] No  [S] Suspend  [?] Help (default is "Y"):

If you select Yes, you will now (by default) get a list of available packages -from the powershell gallery only-.

Lets now install the chocolatey package provider so that we can use PowerShell Packagemanager to install available community packages.

PS C:\Users\Administrator> get-packageprovider -name chocolatey

The provider 'chocolatey v2.8.5.130' is not installed.
chocolatey may be manually downloaded from https://oneget.org/ChocolateyPrototype-2.8.5.130.exe and installed.
Would you like PackageManagement to automatically download and install 'chocolatey' now?
[Y] Yes  [N] No  [S] Suspend  [?] Help (default is "Y"):

If you now once again do a find-package you will suddenly see alot of additional packages that are available from the source ‘chocolatey’. Please be aware however that not all of these packages can be trusted (please read the chocolatey FAQ)

You can install simply the packages by using the install-package, or pipe the install package behind the find-package to also install the dependencies (if any). For example:

Install-package -Name 'GoogleChrome'
Find-Package 'GoogleChrome' -IncludeDependencies | Install-Package

After the software has been installed you can review the installed software by using get-package

Get-Package -Name 'GoogleChrome'

Name                           Version          Source           Summary
----                           -------          ------           -------
GoogleChrome                   45.0.2454.101    C:\Chocolatey...

Here is an example script that you can use for installing some software to your local desktop with powershell packagemanager: oneget_example.ps1

I hope you can enjoy this new functionality as much as myself. This new functionality could greatly help with package deployment and management in the future. You could for example set up your own package repository and deploy your own internal packages using Nuget Server.

Using Powershell to get your server’s uptime!

I have always missed the option in windows to just easily see the uptime from a server.

Ofcourse we have the uptime.exe available from Microsoft, but I wanted to have something available directly from powershell.

For starters we could get the last bootuptime from WMI with the following query

(Get-WmiObject -Class win32_operatingsystem).lastbootuptime
20151005150834.490241+120

Since this is not really in a nice format, lets change it into something we can read

[System.Management.ManagementDateTimeconverter]::ToDateTime((Get-WmiObject -Class win32_operatingsystem).lastbootuptime)
Tuesday, October 6, 2015 10:37:14 AM

Now that we have the bootup time/date in a readable format we can substract this date from our current time/date to get our actual uptime.

((Get-Date)-([System.Management.ManagementDateTimeconverter]::ToDateTime((Get-WmiObject -Class win32_operatingsystem).lastbootuptime)))

Days              : 0
Hours             : 0
Minutes           : 16
Seconds           : 8
Milliseconds      : 736
Ticks             : 9687365862
TotalDays         : 0.0112122290069444
TotalHours        : 0.269093496166667
TotalMinutes      : 16.14560977
TotalSeconds      : 968.7365862
TotalMilliseconds : 968736.5862

And there you go, you can now see the uptime for your server. I took this along a bit and created a powershell function to make it more usable for everyone in the company.

Function Get-Uptime 
{
    <#
            .SYNOPSIS
            Get uptime for Server(s)
            .DESCRIPTION
            This script will provide you the uptime for your servers in easy format
            .PARAMETER Servers
            One or multiple servers
            .EXAMPLE
            Get-Uptime -Server "computername"
            Request the uptime for a server
    #>
    [CmdletBinding(SupportsShouldProcess = $true)]

    param(
        [parameter(Mandatory = $true, HelpMessage = 'Please enter a computername.')]
        [alias('Computernames','Computername','Server','Computer')]
        [string[]]$servers
    )

    ForEach ($server in $servers) 
    {
        Write-Verbose -Message "Retrieving information from $server"
        $uptime = ((Get-Date )-([System.Management.ManagementDateTimeconverter]::ToDateTime((Get-WmiObject -Class win32_operatingsystem -ComputerName $server -ErrorAction SilentlyContinue ).lastbootuptime)))
        $server | Select-Object -Property @{
            Name       = 'Computername'
            Expression = {
                $server
            }
        }, 
        @{
            Name       = 'Days'
            Expression = {
                $uptime.Days
            }
        }, 
        @{
            Name       = 'Hours'
            Expression = {
                $uptime.Hours
            }
        }, 
        @{
            Name       = 'Minutes'
            Expression = {
                $uptime.Minutes
            }
        }, 
        @{
            Name       = 'Seconds'
            Expression = {
                $uptime.Seconds
            }
        }, 
        @{
            Name       = 'Milliseconds'
            Expression = {
                $uptime.Milliseconds
            }
        }
    }
}

Now you only need to type Get-Uptime “servername” to get the uptime for the server you wish 🙂

PS C:\> get-uptime localhost | FT

Computername Days Hours Minutes Seconds Milliseconds
------------ ---- ----- ------- ------- ------------
localhost       0    19      49      32          478

 

Disable privacy sensitive settings in Windows 10

Recently a minor discussion started with one of my Facebook friends, where people found the new data collecting engines from Microsoft a bit annoying. Personally I find that Windows 10 has alot more features and stability to offer, and that these settings should not be the reason for you to hold back on a better operating system. However I do understand some people’s concerns.

Example article:  http://lifehacker.com/what-windows-10s-privacy-nightmare-settings-actually-1722267229

This made me think, there should be a way to just quickly disable all those annoyances. Below you can find the result of a quick Posh script that takes care this for you.

DisablePrivacySettings_Win10.ps1

###########################################################################
## Created by Danny den Braver @29-08-2015
##
## I primary made this script due to a minor discussion that started on FB about the Windows 10 Privacy 'flaws'
## This script will disable most of the 'features' that microsoft uses to gain privacy sensitive data
##
## Currently this script disables Telemetry and DataCollection, Wifi Sense, SmartScreen Filter & Cortana
##########################################################################

#region Disable Telemetry and Data Collection

Write-Verbose -Message 'Disabling: Telemetry and Data Collection' -Verbose

# Create registry key to disable Telemetry
New-ItemProperty -Path "HKLM:\SOFTWARE\Policies\Microsoft\Windows\DataCollection" -Name AllowTelemetry -Value '0' -PropertyType DWord -Force | Out-Null 

# Disabling & Stopping service DiagTrack
Set-Service -name DiagTrack -StartupType Disabled
Stop-Service DiagTrack

# Disabling & Stopping App Push Service
Set-Service -name dmwappushservice -StartupType Disabled
Stop-Service dmwappushservice

#endregion

#region Disable Wifi-Sense (Wifi Sharing)

Write-Verbose -Message 'Disabling: Wifi-Sense (Wifi Sharing)' -Verbose

# Create Registry key into policy to disable Wi-fi Sense
New-ItemProperty -Path "HKLM:\SOFTWARE\Microsoft\WcmSvc\wifinetworkmanager\config" -Name AutoConnectAllowedOEM -Value '0' -PropertyType DWord -Force | Out-Null 

#endregion

#region Disable SmartScreen Filter

Write-Verbose -Message 'Disabling: SmartScreen Filter' -Verbose

# Create Registry key into policy to disable Microsoft SmartScreen
New-ItemProperty -Path "HKLM:\SOFTWARE\Policies\Microsoft\Windows\System" -Name EnableSmartScreen -Value '0' -PropertyType DWord -Force | Out-Null
 
#endregion

#region Disable Cortana

# Read current user
$whoami = whoami
$domain = ($whoami).split("\")[0]
$username = ($whoami).split("\")[1]

if (Test-Path 'C:\Windows\SystemApps\Microsoft.Windows.Cortana_cw5n1h2txyewy\SearchUI.exe')
{
    Write-Verbose -Message 'Disabling: Cortana' -Verbose
    # Change permissions on Cortana folder & executable
    $objUser = New-Object System.Security.Principal.NTAccount($domain, $username)
    $objFile = Get-Acl 'C:\Windows\SystemApps\Microsoft.Windows.Cortana_cw5n1h2txyewy\SearchUI.exe'
    $objFile.SetOwner($objUser)
    Set-Acl -aclobject $objFile -path 'C:\Windows\SystemApps\Microsoft.Windows.Cortana_cw5n1h2txyewy\SearchUI.exe'
    Set-Acl -aclobject $objFile -path 'C:\Windows\SystemApps\Microsoft.Windows.Cortana_cw5n1h2txyewy'
    icacls 'C:\Windows\SystemApps\Microsoft.Windows.Cortana_cw5n1h2txyewy\SearchUI.exe' /grant "$($whoami):(OI)(CI)F"
    icacls 'C:\Windows\SystemApps\Microsoft.Windows.Cortana_cw5n1h2txyewy' /grant "$($whoami):(OI)(CI)F"

    # Rename Cortana Executable so it no longer starts
    Rename-Item 'C:\Windows\SystemApps\Microsoft.Windows.Cortana_cw5n1h2txyewy\SearchUI.exe' 'Disabled.SearchUI.exe'
}

else 
{
    Write-Verbose -Message 'Check: Cortana was already disabled' -Verbose
}

#endregion

Write-Warning -Message 'Please be aware that you will need to restart your computer for settings to take effect'

Scan Cluster Volume Health

I created this function some time ago already when we did not have the SCOM Management Pack for Windows Clusters imported yet.

This script basically scans a Cluster, to scan its current CSV State, and report you the current size/usage/freespace available.

The output of this script can be used to filter out unhealthy volumes, or volumes that are filling up!

Function GetClusterVolumeState{
<#
.SYNOPSIS
Retrieve information about the Cluster Volume Health
.DESCRIPTION
The GetClusterVolumeState function retrieves information about the cluster volumes on a certain cluster.
This information will show the Cluster, Volume, Health and Disk space.
.PARAMETER Clusters
One or multiple clusters you would like to retrieve information from
.EXAMPLE
Retrieve information about the Clustervolumes for Cluster01
RI-GetClusterVolumeState -clusters "Cluster01"
.NOTES
This script was written by Danny den Braver @2013, for questions please contact danny@denbraver.com
#>
[CmdletBinding(SupportsShouldProcess=$true)]
param([array][Parameter(Mandatory=$true)]$Clusters)

foreach ($Cluster in $Clusters){
    # Test Connection availability and continue if $true
    $testconnection = Test-Connection $Cluster -Quiet
    if ($testconnection -eq $true){
        Write-Verbose -Message "Scanning: $Cluster for clusterdisk information"
	    # Get CSV Volumes
	    $CSVDisks = Get-ClusterSharedVolume -Cluster $Cluster
	    foreach ($CSVDisk in $CSVDisks){
		    # Get CSV VolumeInformation
		    $CSVVolumeInfo = $CSVDisk | Select -Expand SharedVolumeInfo
		    $CSVFriendlyName = $CSVVolumeInfo.FriendlyVolumeName
		    $CSVVolume = ($CSVFriendlyName.Split("\")[2]).ToLower()
		    $CSVState = $CSVDisk.State
		    # Get CSV free space
		    [int]$CSVDiskDriveFreeSpace = ([math]::round((($CSVVolumeInfo | Select -Expand Partition).FreeSpace / 1GB), 0))
		    # Get CSV total space
		    [int]$CSVDiskSpace = ([math]::round((($CSVVolumeInfo | Select -Expand Partition).Size / 1GB), 0))
		    # Get CSV used Space
		    [int]$CSVDiskDriveUsedSpace = [int]$CSVDiskSpace - [int]$CSVDiskDriveFreeSpace
		    # Get CSV Health
		    if ($CSVState -eq "Online"){
			    if ($CSVVolumeInfo.MaintenanceMode -eq $False){
				    if ($CSVVolumeInfo.RedirectedAccess -eq $True){
					    $CSVHealth = "Warning"
					    $CSVHealthDetails = 'Volume is in redirected mode.'
				    }
				    else {
					    $CSVHealth = "Healthy"
					    $CSVHealthDetails = 'Volume is healthy.'
				    }
			    }
			    else {
				    $CSVHealth = "Maintenance"
				    $CSVHealthDetails = 'Volume is in maintenance mode."'	
			    }									
		    }
		    else {
			    $CSVHealth = "Critical"
			    $CSVHealthDetails = 'Volume is in offline state.'
		    }
 
		    # CSV Output
            $clustername = $cluster -replace ".eu.rabonet.com",""
            $clustername | select   @{l="Clustername";e={$Clustername}},
                                    @{l="Volume"; e={"$CSVVolume"}},
                                    @{l="DiskSpaceGB"; e={"$CSVDiskSpace"}},
                                    @{l="UsedSpaceGB"; e={"$CSVDiskDriveUsedSpace"}},
                                    @{l="FreeSpaceGB"; e={"$CSVDiskDriveFreeSpace"}},
                                    @{l="Health"; e={"$CSVHealth"}},
                                    @{l="Health Description"; e={"$CSVHealthDetails"}}
	    }
    }
    else { Write-Warning "Could not connect to $Cluster" }
}
}

 

Make a SSH Connection using Powershell

Ever needed to connect to a hardware or unix interface from a windows box? For example to manage HP Servers / Interfaces, or to run some code on a Linux appliance?

Over at Powershelladmin.com they have an answer to this: SSH-Sessions powershell module.

Copy the SSH-Sessions folder to your C:\Windows\System32\WindowsPowerShell\v1.0\Modules directory and then unblock the SSH.Net library using Unblock-File C:\Windows\System32\WindowsPowerShell\v1.0\Modules\SSH-Sessions\Renci.SshNet.dll

After that you can just Import-module the SSH-Sessions and you’re on your way:

get-help *ssh*

Name                    Category  Synopsis
----                    --------  --------
Get-SshSession          Function  Shows all, or the specified, SSH sessions in the global $SshSessions var...
Remove-SshSession       Function  Removes opened SSH connections. Use the parameter -RemoveAll to remove a...
New-SshSession          Function  Creates SSH sessions to remote SSH-compatible hosts, such as Linux...
Invoke-SshCommand       Function  Invoke/run commands via SSH on target hosts to which you have already op...
Enter-SshSession        Function  Enter a primitive interactive SSH session against a target host....