samples/Tools.psm1


Function Get-WindowsVersion {
    <#
    .SYNOPSIS
    Get Windows version information
    .DESCRIPTION
    This is a PowerShell version of the winver.exe utility. This commands uses PowerShell remoting to query the registry on a remote machine to retrieve Windows version information.The parameters are the same as in Invoke-Command.
    .PARAMETER Computername
    Specifies the computers on which the command runs. The default is the local computer.
 
    When you use the ComputerName parameter, Windows PowerShell creates a temporary connection that is used only to run the specified command and is then closed. If you need a persistent connection, use the Session parameter.
 
    Type the NETBIOS name, IP address, or fully qualified domain name of one or more computers in a comma-separated list. To specify the local computer, type the computer name, localhost, or a dot (.).
 
    To use an IP address in the value of ComputerName , the command must include the Credential parameter. Also, the computer must be configured for HTTPS transport or the IP address of the remote computer must be included in the WinRM TrustedHosts list on the local computer. For instructions for adding a computer name to the TrustedHosts list, see "How to Add a Computer to the Trusted Host List" in about_Remote_Troubleshooting.
 
    On Windows Vista and later versions of the Windows operating system, to include the local computer in the value of ComputerName , you must open Windows PowerShell by using the Run as administrator option.
    .PARAMETER Credential
    Specifies a user account that has permission to perform this action. The default is the current user.
 
    Type a user name, such as User01 or Domain01\User01. Or, enter a PSCredential object, such as one generated by the Get-Credential cmdlet. If you type a user name, this cmdlet prompts you for a password.
    .PARAMETER UseSSL
    Indicates that this cmdlet uses the Secure Sockets Layer (SSL) protocol to establish a connection to the remote computer. By default, SSL is not used.
 
    WS-Management encrypts all Windows PowerShell content transmitted over the network. The UseSSL parameter is an additional protection that sends the data across an HTTPS, instead of HTTP.
 
    If you use this parameter, but SSL is not available on the port that is used for the command, the command fails.
    .PARAMETER ThrottleLimit
    Specifies the maximum number of concurrent connections that can be established to run this command. If you omit this parameter or enter a value of 0, the default value, 32, is used.
 
    The throttle limit applies only to the current command, not to the session or to the computer.
    .PARAMETER Authentication
    Specifies the mechanism that is used to authenticate the user's credentials. The acceptable values for this
    parameter are:
 
    - Default
    - Basic
    - Credssp
    - Digest
    - Kerberos
    - Negotiate
    - NegotiateWithImplicitCredential
 
    The default value is Default.
 
    CredSSP authentication is available only in Windows Vista, Windows Server 2008, and later versions of the Windows operating system.
 
    For information about the values of this parameter, see the description of the AuthenticationMechanismEnumeration (http://go.microsoft.com/fwlink/?LinkID=144382) in theMicrosoft Developer Network (MSDN) library.
 
    CAUTION: Credential Security Support Provider (CredSSP) authentication, in which the user's credentials are passed to a remote computer to be authenticated, is designed for commands that require authentication on more than one resource, such as accessing a remote network share. This mechanism increases the security risk of the remote operation. If the remote computer is compromised, the credentials that are passed to it can be used to control the
    network session.
    .EXAMPLE
    PS C:\> Get-WindowsVersion
 
    ProductName : Windows 10 Pro
    EditionID : Professional
    ReleaseId : 1809
    Build : 17763.195
    InstalledUTC : 12/17/2018 2:18:37 PM
    Computername : BOVINE320
 
    Query the local host.
    .EXAMPLE
    PS C:\scripts> get-windowsversion -Computername srv1,srv2,win10 -Credential company\artd | format-table
 
 
    ProductName EditionID ReleaseId Build InstalledUTC Computername
    ----------- --------- --------- ----- ------------ ------------
    Windows Server 2016 Standard Evaluation ServerStandardEval 1607 14393.2273 12/26/2018 4:07:25 PM SRV1
    Windows Server 2016 Standard Evaluation ServerStandardEval 1607 14393.2273 12/26/2018 4:08:07 PM SRV2
    Windows 10 Enterprise Evaluation EnterpriseEval 1703 15063.1387 12/26/2018 4:08:11 PM WIN10
 
 
    Get windows version information from remote computers using an alternate credential.
 
    .Example
    PS C:\> Get-WindowsVersion -Computername win10 -AsString
    Windows 10 Enterprise Evaluation Version 1703 (OS Build 15063.1387)
 
    Get a string
    .INPUTS
    System.String
    .OUTPUTS
    Custom object
    .NOTES
    Learn more about PowerShell: http://jdhitsolutions.com/blog/essential-powershell-resources/
    .LINK
    WinVer.exe
    .LINK
    Invoke-Command
    #>


    [cmdletbinding()]
    [OutputType("custom object")]
    [alias('wver')]

    Param (
        [Parameter(
            Position = 0,
            ValueFromPipeline,
            ValueFromPipelineByPropertyName
        )]
        [ValidateNotNullOrEmpty()]
        [string[]]$Computername = $env:COMPUTERNAME,
        [PSCredential]$Credential,
        [switch]$UseSSL,
        [Int32]$ThrottleLimit,
        [ValidateSet('Default', 'Basic', 'Credssp', 'Digest', 'Kerberos', 'Negotiate', 'NegotiateWithImplicitCredential')]
        [ValidateNotNullorEmpty()]
        [string]$Authentication = "Default"
    )

    Begin {
        Write-Verbose "Starting $($MyInvocation.MyCommand)"

        $sb = {
            $RegPath = 'HKLM:\SOFTWARE\Microsoft\Windows nt\CurrentVersion\'

            Get-ItemProperty -Path $RegPath | Select-Object -Property ProductName, EditionID, ReleaseID,
            @{Name = "Build"; Expression = { "$($_.CurrentBuild).$($_.UBR)" } },
            @{Name = "InstalledUTC"; Expression = { ([datetime]"1/1/1601").AddTicks($_.InstallTime) } },
            @{Name = "Computername"; Expression = { $env:computername } }

        } #close scriptblock

        #update PSBoundParameters so it can be splatted to Invoke-Command
        $PSBoundParameters.Add("ScriptBlock", $sb) | Out-Null
        $PSBoundParameters.add("HideComputername", $True) | Out-Null
    } #begin

    Process {
        if (-Not $PSBoundParameters.ContainsKey("Computername")) {
            #add the default value if nothing was specified
            $PSBoundParameters.Add("Computername", $Computername) | Out-Null
        }
        $PSBoundParameters | Out-String | Write-Verbose
        $results = Invoke-Command @PSBoundParameters | Select-Object -Property * -ExcludeProperty RunspaceID, PS*
        if ($AsString) {
            #write a version string for each computer
            foreach ($result in $results) {
                "{0} Version {1} (OS Build {2})" -f $result.ProductName, $result.releaseID, $result.build
            }
        }
        else {
            $results
        }
    } #process

    End {
        Write-Verbose "Ending $($MyInvocation.MyCommand)"

    } #end
} #close function


Function Get-WindowsVersionString {
    <#
    .SYNOPSIS
    Get Windows version information
    .DESCRIPTION
    This is a PowerShell version of the winver.exe utility. This commands uses PowerShell remoting to query the registry on a remote machine to retrieve Windows version information.The parameters are the same as in Invoke-Command. The command writes a string of version information.
    .PARAMETER Computername
    Specifies the computers on which the command runs. The default is the local computer.
 
    When you use the ComputerName parameter, Windows PowerShell creates a temporary connection that is used only to run the specified command and is then closed. If you need a persistent connection, use the Session parameter.
 
    Type the NETBIOS name, IP address, or fully qualified domain name of one or more computers in a comma-separated list. To specify the local computer, type the computer name, localhost, or a dot (.).
 
    To use an IP address in the value of ComputerName , the command must include the Credential parameter. Also, the computer must be configured for HTTPS transport or the IP address of the remote computer must be included in the WinRM TrustedHosts list on the local computer. For instructions for adding a computer name to the TrustedHosts list, see "How to Add a Computer to the Trusted Host List" in about_Remote_Troubleshooting.
 
    On Windows Vista and later versions of the Windows operating system, to include the local computer in the value of ComputerName , you must open Windows PowerShell by using the Run as administrator option.
    .PARAMETER Credential
    Specifies a user account that has permission to perform this action. The default is the current user.
 
    Type a user name, such as User01 or Domain01\User01. Or, enter a PSCredential object, such as one generated by the Get-Credential cmdlet. If you type a user name, this cmdlet prompts you for a password.
    .PARAMETER UseSSL
    Indicates that this cmdlet uses the Secure Sockets Layer (SSL) protocol to establish a connection to the remote computer. By default, SSL is not used.
 
    WS-Management encrypts all Windows PowerShell content transmitted over the network. The UseSSL parameter is an additional protection that sends the data across an HTTPS, instead of HTTP.
 
    If you use this parameter, but SSL is not available on the port that is used for the command, the command fails.
    .PARAMETER ThrottleLimit
    Specifies the maximum number of concurrent connections that can be established to run this command. If you omit this parameter or enter a value of 0, the default value, 32, is used.
 
    The throttle limit applies only to the current command, not to the session or to the computer.
    .PARAMETER Authentication
    Specifies the mechanism that is used to authenticate the user's credentials. The acceptable values for this
    parameter are:
 
    - Default
    - Basic
    - Credssp
    - Digest
    - Kerberos
    - Negotiate
    - NegotiateWithImplicitCredential
 
    The default value is Default.
 
    CredSSP authentication is available only in Windows Vista, Windows Server 2008, and later versions of the Windows operating system.
 
    For information about the values of this parameter, see the description of the AuthenticationMechanismEnumeration (http://go.microsoft.com/fwlink/?LinkID=144382) in theMicrosoft Developer Network (MSDN) library.
 
    CAUTION: Credential Security Support Provider (CredSSP) authentication, in which the user's credentials are passed to a remote computer to be authenticated, is designed for commands that require authentication on more than one resource, such as accessing a remote network share. This mechanism increases the security risk of the remote operation. If the remote computer is compromised, the credentials that are passed to it can be used to control the
    network session.
    .EXAMPLE
    PS C:\> Get-WindowsVersionString -Computername win10 -credential company\artd
    Windows 10 Enterprise Evaluation Version 1703 (OS Build 15063.1387)
 
    Get a string version of Windows version information from a remote computer and use an alternate credential.
    .EXAMPLE
    PS C:\> Get-WindowsVersionString
    Windows 10 Pro Version 1809 (OS Build 17763.195)
 
    Get version information for the current computer.
    .EXAMPLE
    PS C:\> import-csv .\company.csv | Select Computername,@{Name="Version";Expression={ get-windowsversionstring $_.computername}}
 
    Computername Version
    ------------ -------
    Dom1 Windows Server 2016 Standard Evaluation Version 1607 (OS Build 14393.2273)
    Srv1 Windows Server 2016 Standard Evaluation Version 1607 (OS Build 14393.2273)
    Srv2 Windows Server 2016 Standard Evaluation Version 1607 (OS Build 14393.2273)
    Win10 Windows 10 Enterprise Evaluation Version 1703 (OS Build 15063.1387)
 
    Import data from a CSV file and display version information.
    .INPUTS
    System.String
    .OUTPUTS
    System.String
    .NOTES
    Learn more about PowerShell: http://jdhitsolutions.com/blog/essential-powershell-resources/
    .LINK
    Get-WindowsVersion
    .lINK
    Winver.exe
 
    #>

    [cmdletbinding()]
    [OutputType("system.string")]

    Param (
        [Parameter(
            Position = 0,
            ValueFromPipeline,
            ValueFromPipelineByPropertyName
        )]
        [ValidateNotNullOrEmpty()]
        [string[]]$Computername = $env:COMPUTERNAME,
        [PSCredential]$Credential,
        [switch]$UseSSL,
        [Int32]$ThrottleLimit,
        [ValidateSet('Default', 'Basic', 'Credssp', 'Digest', 'Kerberos', 'Negotiate', 'NegotiateWithImplicitCredential')]
        [ValidateNotNullorEmpty()]
        [string]$Authentication = "Default"
    )

    Begin {
        Write-Verbose "Starting $($MyInvocation.MyCommand)"
    } #begin

    Process {
        $results = Get-WindowsVersion @PSBoundParameters

        #write a version string for each computer
        foreach ($result in $results) {
            "{0} Version {1} (OS Build {2})" -f $result.ProductName, $result.releaseID, $result.build
        }
    } #process

    End {
        Write-Verbose "Ending $($MyInvocation.MyCommand)"
    } #end
}
function Get-OSInfo {
    [CmdletBinding()]
    param(
        [Parameter(Position = 0, ValueFromPipeline)]
        [ValidateNotNullOrEmpty()]
        [string[]]$ComputerName = $env:COMPUTERNAME
    )
    BEGIN {
        Write-Verbose "Starting $($MyInvocation.MyCommand)"
    }
    PROCESS {
        ForEach ($computer in $computername) {
            try {
                $connected = $True
                Write-Verbose "Attempting $computer"
                $os = Get-CimInstance -ComputerName $computer -ClassName Win32_OperatingSystem -ErrorAction Stop
            }
            catch {
                $connected = $false
                Write-Verbose "Connection to $computer failed. $($_.exception.message)."
            }
            if ($connected) {
                Write-Verbose "Connection to $computer succeeded"
                $cs = Get-CimInstance -ComputerName $computer -ClassName Win32_ComputerSystem
                $props = @{
                    'ComputerName' = $os.CSName
                    'OSVersion'    = $os.version
                    'Manufacturer' = $cs.manufacturer
                    'Model'        = $cs.model
                }
                New-Object -TypeName PSObject -Property $props
            }
        }
    }
    END {
        Write-Verbose "Ending $($MyInvocation.MyCommand)"
    }
}