All posts by Frank Contreras

What processes are listening on HTTP/HTTPS related ports?

Working in a vacuum when initially looking at a server is par for course.  My one clue is that the server for a web application of sorts.   However, one does not know what the application is or what software may be serving up HTTP/HTTPS.  Standards are that the server would be serving up on ports 80 and/or 443, respectively.   Many applications will serve up this kind of traffic on variations like 8080 or, essentially, *80 and *443.  I needed a script to quickly see what processes may be listening on those ports.  This helps me gain insight to track down pieces and help the application owner/team investigate further.  Here’s the script:

# Look for listening ports on *80 and *443 with process ID
$Processes = @{}
Get-Process -IncludeUserName | ForEach-Object {
 $Processes[$_.Id] = $_
}

Get-NetTCPConnection | 
 Where-Object { ($_.State -eq "Listen") -and ($_.LocalPort -like '*80' -or $_.LocalPort -like '*443') } |
 Select-Object LocalAddress,
 LocalPort,
 @{Name="PID"; Expression={ $_.OwningProcess }},
 @{Name="ProcessName"; Expression={ $Processes[[int]$_.OwningProcess].ProcessName }}, 
 @{Name="UserName"; Expression={ $Processes[[int]$_.OwningProcess].UserName }} |
 Sort-Object -Property ProcessName, UserName |
 Format-Table -AutoSize

Who initiated the reboot?

This Powershell one liner will check the event log of a remote computer to see what initiated the shutdown or reboot.  If the server just crashed or power was interrupted you can filter on a different Event ID.

Get-EventLog -ComputerName <servername> -LogName System | Where-Object {$_.EventID -eq 1074} | Select-Object -First 1 | FL *

Error 14098 the Component Store has been corrupted

When the OS is serviced, the component store is updated. It is part of Windows Imaging and Servicing stack. If you got the error 14098 ‘The component store has been corrupted’, it means that something went wrong with Windows updates and its packages.

To fix the component store, you can use DISM – Deployment Image Servicing and Management tool.

/RestoreHealth: This checks for component store corruption, records the corruption to C:\Windows\Logs\CBS\CBS.log and fixes the corruption using Windows Update or using your Windows installation source.

Dism /Online /Cleanup-Image /RestoreHealth

Clean up the WinSxS folder on Windows 2012 R2

Use the /AnalyzeComponentStore to analyze the size of the Component Store (WinSxS folder) in Windows. The AnalyzeComponentStore option is available in Windows 8.1 Windows Server 2012 R2.

dism.exe /online /Cleanup-Image /AnalyzeComponentStore

Dism.exe removes superseded and unused system files from a system with the /StartComponentCleanup parameter.

dism.exe /online /Cleanup-Image /StartComponentCleanup

Using the /ResetBase switch with the /StartComponentCleanup parameter of dism.exe, all superseded versions of every component in the component store is removed.  All existing service packs and updates cannot be uninstalled after this command is completed. This will not block the uninstallation of future service packs or updates.

dism.exe /online /Cleanup-Image /StartComponentCleanup /ResetBase

The /SPSuperseded parameter removes any backup components needed for de-installation of a service pack. The service pack cannot be uninstalled after this command is completed.

dism.exe /online /Cleanup-Image /SPSuperseded

 

Can’t Install Roles or Features on Windows 2012 R2

I came across a really strange issue.  When going through the Add Roles and Features Wizard, I tried to click next to the Server Roles page.  The wizard then shows a red bar with the following error, “The request to list features available on the specified server failed.”

Doing an SFC /SCANNOW like so many internet searches says to do, does not clear the issue.  The reason seems that the server was in a pending reboot state for changes to be made.  Rebooting never makes any changes.  This state also prevents using DISM from fixing any corruption.

It turns out that one can boot into the repair console to get to files offline.  Navigate to the C:\Windows\WinSxS directory and rename the pending.xml file to something like pending.xml.old.  This tricks Windows into thinking that nothing else is pending a reboot and allows one to use SFC and DISM to clean up system files.

It looks like a ton of Windows updates went in, but didn’t get installed correctly.  Checking for Windows updates produced over 77 important updates as opposed to the 3 that were being presented before renaming pending.xml.

SFC and DISM fixes went in, a couple of reboots and I am now able to properly install roles and features.

Failed to register Fiddler as the system proxy.

I installed Fiddler on a new Windows 10 workstation.  When starting up Fiddler, I get the following error message: “Failed to register Fiddler as the system proxy.”

When I try to capture traffic (F12) I get the same error message. No
traffic is captured.

Netstat shows Fiddler is listening:

C:\>netstat -an | find "8888"
TCP 127.0.0.1:8888 0.0.0.0:0 LISTENING

After searching high and low, the fix is quite simple.  Just go and start the WinHTTP Web Proxy Auto-Discovery Service.  It was disabled on my workstation.  After that, Fiddler works as expected.

Get the Microsoft SQL version query

SELECT
  CASE 
     WHEN CONVERT(VARCHAR(128), SERVERPROPERTY ('productversion')) like '8%' THEN 'SQL2000'
     WHEN CONVERT(VARCHAR(128), SERVERPROPERTY ('productversion')) like '9%' THEN 'SQL2005'
     WHEN CONVERT(VARCHAR(128), SERVERPROPERTY ('productversion')) like '10.0%' THEN 'SQL2008'
     WHEN CONVERT(VARCHAR(128), SERVERPROPERTY ('productversion')) like '10.5%' THEN 'SQL2008 R2'
     WHEN CONVERT(VARCHAR(128), SERVERPROPERTY ('productversion')) like '11%' THEN 'SQL2012'
     WHEN CONVERT(VARCHAR(128), SERVERPROPERTY ('productversion')) like '12%' THEN 'SQL2014'
     WHEN CONVERT(VARCHAR(128), SERVERPROPERTY ('productversion')) like '13%' THEN 'SQL2016'     
     ELSE 'unknown'
  END AS MajorVersion,
  SERVERPROPERTY('ProductLevel') AS ProductLevel,
  SERVERPROPERTY('Edition') AS Edition,
  SERVERPROPERTY('ProductVersion') AS ProductVersion

Get-ADUser and Filtering out $null values

Are you having challenges with the Get-ADUser commandlet not pitching errors on a -Filter producing $null results?  Intuitively, it would make sense for the -Filter to filter those out with a -ne $null.  Well, it doesn’t work that way.  There is a Where-Object commandlet that one can pipe to  and filter out those things.  In my example, I chose to filter out $null User Principal Names.  Here’s the example:

$myNonNullUsers = Get-ADUser -Filter { enabled -eq $true } -Properties * | Where-Object {$_.userPrincipalName -ne $null}

Automatically Assign Licences to New Office 365 Accounts

Here’s the scenario: Users are created in Active Directory, on-premise.  The AD Sync Service then will sync up the user account to Office 365.  However, a license is not assigned.  The rule of thumb when assigning new licenses is that people in the call center get an E1 license and the rest of the employees get an E3 license.  The identifying characteristic for the call center users is that their email address is <someone>@mycallcenter.com and everyone else has a different domain for their email.  For your use case, you may have other specific identifiers to help determine the appropriate license.  If one size fits all, you can eliminate the the lines to change to an E1 license and leave the default.

I chose to use a security group to identify users that need a license assigned.  In this case it’s “ADGroup-UsersNeedingLicenses”  When the script runs it will iterate through all members of that security group  and check to see if the account has synchronized up with Office 365.  If the account is there, it will evaluate which license to assign and then assign it.  It will then get the user’s licenses from Office 365 and display them so you can validate that it was updated.  It then removes the user from the security group and we’re done.

If you like, you can set this on a scheduled task to automatically assign licenses to new users on an interval.  One would need to store credentials in a file in order for it to be automated.  I like it because it’s one less administrative task I need to deal with.  I can create the account in AD then go take care of other things.  I come back after a bit and then the user is synchronized and licensed.

<# Get credentials to connect to Office 365 using PowerShell#>
$Password = Get-Content j:\myscripts\ADCredentials.txt | ConvertTo-SecureString
$credential = New-Object System.Management.Automation.PsCredential("ServiceAccount@company.onmicrosoft.com",$password)

<# Connect to MSOL #>
Connect-MsolService -Credential $credential

<# Get AD Users designated for license assignment #>
$usersNeedingLicense = Get-ADGroupMember -Identity ADGroup-UsersNeedingLicenses

<# Iterate through the collection of AD users designated for license assignment #>
ForEach ($ADUser in $usersNeedingLicense){
 $ADUser = Get-ADUser -Identity $ADUser -Properties *
 "AD UPN: " + $ADUser.UserPrincipalName
 
 Try {
 $o365User = Get-MsolUser -UserPrincipalName $ADUser.UserPrincipalName -ErrorAction Stop
 $licenseType = "mycompany:ENTERPRISEPACK" <# set default to E3 #>
 If ( $ADUser.UserPrincipalName.Contains("@mycallcenter.com")){$licenseType="mycompany:STANDARDPACK"} <# Assign E1 #>

 "Assign: $licenseType"
 <# Locate and assign license using matching UPN #>
 Set-MsolUser -UserPrincipalName $ADUser.UserPrincipalName -UsageLocation "US" <# Set user licensing to Unites States #>
 Set-MsolUserLicense -UserPrincipalName $ADUser.UserPrincipalName -AddLicenses $licenseType
 <# view for validation #>
 Get-MsolUser -UserPrincipalName $ADUser.UserPrincipalName | fl UserPrincipalName, Licenses
 <# Remove AD user from ADGroup-UsersNeedingLicenses #>
 Remove-ADGroupMember -Identity ADGroup-UsersNeedingLicenses -Members $ADUser.SamAccountName -Confirm:$false
 }

 Catch [System.Exception]{
 $ADUser.UserPrincipalName + " is not in Office 365 yet."
 $error
 }
 Finally {$error.Clear() }
}

Use SCP to copy files from Linux using PowerShell

There’s a lot of different tools out there to essentially SSH to a Linux host.  They seem to come short when one needs to use secure copy.  WinSCP has been around forever and is a relatively mature tool for doing SCP on a Windows client.  My requirement is to copy files from a Linux server to a Windows client.  WinSCP seems to be the best fit for my one need.  Here are the general steps to getting it done:

  • First install WinSCP wrapper to enable use of SCP from PowerShell.  Windows Management Framework 5.0 is a prerequisite.
  • Run the WinSCP application to collect the key from the target Linux host.
  • Generate credentials to be used by a script to copy files.  Run a script to copy the files.
  • If needed, set up a scheduled task to run the copy script on an interval.

Download WinSCP .NET assembly for use with PowerShell: https://winscp.net/eng/docs/library_powershell#powershell_scripting

In PowerShell running as administrator, run the following:

Install-Module -Name WinSCP

Check the install by running the following:

Get-Command -Module WinSCP

Store credentials to be used in a later script.
Save Password to File
$credential = Get-Credential
$credential.Password | ConvertFrom-SecureString | Set-Content G:\scripts\PasswordFile.txt

Run a script the uses the password file to access the Linux server and copy over your files.
$session = New-WinSCPSession -Hostname <Linux Host> -Credential $credential -SshHostKeyFingerprint "ssh-rsa-xx-xx-xx-xx-xx-xx-xx-xx-xx-xx-xx-xx-xx-xx-xx-xx"

Receive-WinSCPItem -WinSCPSession $session -Path “/…/somefile” -Destination “C:\folder\destination\etc\”

Remove-WinSCPSession -WinSCPSession $session