Powershell Win32_ServerConnection on TS Server 2012 no result - windows

I'm trying to execute a simple command on one of a TS part of a RDS farm and I get no result. I just want to see every connection on the TS using:
Get-WmiObject Win32_ServerConnection -ComputerName MYTSSERVER
and I get no result at all. Any idea what could be the cause?
Thank you

Win32_ServerConnection shows active connections to network shares on the machine. If you do not have active network shares or connections to them there will be no results.
I assume since they're terminal servers in an RDS farm that you're looking for remote sessions in which case you want Win32_LoggedOnUser. That said, Win32_LoggedOnUser doesn't clear sessions that have been disconnected or even closed. It shows all sessions since the last computer reboot whether that information is still valid or not.
It's incredibly annoying but the best way to list real and active sessions is to list all copies of explorer.exe running on the machine and who they belong to or use the cmd application query.exe. There are ways in PowerShell to turn the output of query.exe into objects:
$Users = query user /server:TERMSERV01 2>&1
$Users = $Users | ForEach-Object { (($_.trim() -replace ">" -replace "(?m)^([A-Za-z0-9]{3,})\s+(\d{1,2}\s+\w+)", '$1 none $2' -replace "\s{2,}", "," -replace "none", $null)) } | ConvertFrom-Csv
$Users

Related

Adding values from multiple computers with custom headers in a single csv

I need to accomplish the scenario below and for that I have to create a couple of powershell scripts to accomplish it.
The environment: Windows servers and Windows clients
Scenario
1- Create a script to be run in a specific time every day (with Task Scheduler) on windows clients. This script will push the current computer's hostname and IP address to a csv file with a specific headers (let's call these "Hostnames" and "IP Address"). These header shouldn't be changed as these scripts run from multiple computers at that time and all computers' data should be appended to each header, not overwrite them as this operation continues.
2- From a server, (after 15 mins) as fetching this "computer" list (csv), there should be a ping check for each of them using their IP addresses. If pings are successful on these remote computers, it should say "This computer is up" next to the each computer name and its IP address. If pings are unsuccessful, it should say "This computer is down" next to the each computer name and its IP address. Above these "status" information, there should be another header (let's say "IsAlive"). This header should be added to the csv as well.
So with this setup, I could be able to learn which computers are UP at a specific time and after I trigger some actions them, I could be able to learn if they're still up or down.
To be honest, I couldn't take a long way for it. I started to write a script about the first step but I couldn't combine the headers with values adding under them.
$header="Hostname"
$outputfile="\\10.10.10.40\reports\upcomputers.csv"
Add-Content $outputfile -Value $header
$hostname >> $outputfile
If I use this script (even if with one header), it's adding "NULL" after each alphabet of hostname and it doesn't append the other hostname under the "Hostname" header.
Additionally, I have no idea where to start adding the third header (IsAlive) and add each Test-NetConnection query's output as checking their IP addresses. I request you to show me a way to start with this section as well.
Finally, my output should be like that;
For the first step;
For the second step;
Thank you for your help and information
Stated on the main body of the request
Stage 2:
The easy way of doing this using PSCustomobject. Please find the sample code below:
$outputcsv = "C:\PowerShell\pingstatus.csv"
$hostlist = import-csv "C:\PowerShell\hostlist.csv"
$result = foreach($line in $hostlist){
$pingtest = Test-Connection -ComputerName $line.Hostname -Quiet -Count 1 -ErrorAction SilentlyContinue
if($pingtest) {
$OutputMessage = "This computer is up"
}
else {
$OutputMessage = "This computer is down"
}
[pscustomobject][ordered]#{
HostName = $line.Hostname
IPAddress = $line.IPaddress
IsAlive = $OutputMessage
}
}
$result | Export-csv -Path $outputcsv -NoTypeInformation
The Hostname and IPAddress input will be taken as input.
Note: Your input csv file should contain Hostname IPaddress as header.
Stage1:
why not?
$outputfile="\\10.10.10.40\reports\upcomputers.csv"
$serverDetails = [PSCustomObject]#{
Hostname = "$env:COMPUTERNAME"
IPAddress = (Get-WmiObject -Class Win32_NetworkAdapterConfiguration | where {$_.DHCPEnabled -ne $null -and $_.DefaultIPGateway -ne $null}).IPAddress | Select-Object -First 1
}
$serverDetails | Export-csv $outputfile -Append -NoTypeInformation
There are multiple ways to get IP address a computer, I used Get-WMIObject. You may use other simple ways like Test-Connection or Get-NetIPAddress.
To learn more: Please see
[PsCustomObject]: https://learn.microsoft.com/en-us/powershell/scripting/learn/deep-dives/everything-about-pscustomobject?view=powershell-7.3

Trying to back up my Bitlocker Key to ADDS Through Script

I'm trying to automatize the process of storing BitLocker Keys to ADDS.
I wanna be able to run the following script at logon, in order to do that, as the OS is deployed through WDS which already encrypts the drive:
$BitVolume = Get-BitLockerVolume -MountPoint $env:SystemDrive
$RecoveryKey = $BitVolume.KeyProtector | Where-Object { $_.KeyProtectorType -eq 'RecoveryPassword' }
Backup-BitLockerKeyProtector -MountPoint $env:SystemDrive -KeyProtectorId $RecoveryKey.KeyProtectorID
BackupToAAD-BitLockerKeyProtector -MountPoint $env:SystemDrive -KeyProtectorId $RecoveryKey.KeyProtectorID
I always get access denied as this has to run as admin...
Is there any command I can use prior the code to run it as admin?
I've googled but I found no useful info to actually do this...
As for the access denied part... as was already sated, you need to start your PowerShell session as an admin. However, as a point of note about your code, you are only targeting the system/os volume... which may not be the only volume that's encrypted. If you want to programmatically backup all of the encrypted volumes, may I suggest one of the two following options...
One-liner:
Get-BitLockerVolume | where {$_.VolumeStatus -like "FullyEncrypted"} | foreach {foreach($Key in $_.KeyProtector){if($Key -like "RecoveryPassword"){Backup-BitLockerKeyProtector -MountPoint $_.mountpoint -KeyProtectorId $key.KeyProtectorId}}}
Or, if you prefer something a little bit easier to read...
Script Block:
foreach ($BLV in Get-BitLockerVolume){
if ($BLV.VolumeStatus -like "FullyEncrypted"){
foreach ($Key in $BLV.KeyProtector) {
if ($Key -like "RecoveryPassword") {
Backup-BitLockerKeyProtector -MountPoint $BLV.MountPoint -KeyProtectorId $Key.KeyProtectorId
}#if
}#foreach
}#if
}#foreach
Neither is super eloquent... but, with this method it will grab all of the encrypted volumes on the system and add them to AD. You would need to modify the code slightly to add the AAD backup option you cited of course.
P.S. I'm only responding because I recently had to solve this problem of multi-volume backups as a one-liner solution and figured I would share it since your post was a top search result when I looked for a pre-canned solution. Cheers! :)

WMIMethodException with .InstallProductKey

First off, this is my first post, so if I incorrectly posted this in the wrong location, please let me know.
So, what we're trying to accomplish is building a powershell script that we can throw on our workstation image so that once our Windows 10 boxes are done imaging, that we can click on a powershell script, have it pull the key from the BIOS, and automagically activate it. That being said, here is the script that we've put together from various sources.
(Get-WmiObject -query ‘select * from SoftwareLicensingService’).OA3xOriginalProductKey | out-file c:\license.txt
$computer = gc env:computername
$key = get-content c:\license.txt
$service = get-wmiObject -query “select * from SoftwareLicensingService” -computername $computer
$service.InstallProductKey($key) <--------THIS IS WHERE IT FAILS
$service.RefreshLicenseStatus()
We start running into the issues on the line $service.InstallProductKey($key). It seems, that no matter how we try to invoke that, it will consistently fail with the error "Exception calling "InstallProductKey"". I've even replaced the variable ($key) with the specific activation key, and it STILL fails with the same error.
The reason we have it outputting to a license txt file part way through is so that we can verify that the command is indeed pulling the product key (which it is).
At this point, I'm not sure where to go. It seems that people have tried to do this before, however, nobody has really wrapped up their posting with what worked and/or what didn't. I can't imagine that this is impossible, but I'm also not fond of wasting anymore time than needed, so anybody that has any insight into this issue, I'd be very grateful.
We've gotten it to work on two machines that were previously activated, and later deactivated, but on new machines that have been freshly imaged, and have yet to be activated, it will fail every time.
Two things as per my observation:
(Get-WmiObject -query ‘select * from SoftwareLicensingService’).OA3xOriginalProductKey | out-file c:\license.txt
I don't think that it is returning any value to your license.txt.
If yes, then I would like you to see if there is any space before and after the license key. You can use trim during getting the content from the file.
Second thing, when you are getting the content from the file make sure it is not separating into multiple lines. In that case, you have to cast it as string like [String]$key or you can call toString() method for this.
One more important thing is to refresh after the installation.
$service.RefreshLicenseStatus()
Note: Make sure you are running the shell in elevated mode.
Alternative: Try Hardcoding the values and see the result
$key = "XXXXX-XXXXX-XXXXX-XXXXX-XXXXX" # hardcode the key
$computer= "Computer01" # Hardcode the computer
$service = get-wmiObject -query "select * from SoftwareLicensingService" -computername $computer
$service.InstallProductKey($key)
$service.RefreshLicenseStatus()
For further thing ,please post the exact error.
Hope it helps...!!!
Found out that the key from Get-WmiObject has whitespace on the end. The original command will work if a .Trim() is added. Also not running as administrator will result in the same error.
(Get-WmiObject -query ‘select * from SoftwareLicensingService’).OA3xOriginalProductKey | out-file c:\license.txt
$computer = gc env:computername
$key = (get-content c:\license.txt).Trim() #trim here
$service = get-wmiObject -query “select * from SoftwareLicensingService” -computername $computer
$service.InstallProductKey($key)
$service.RefreshLicenseStatus()

Retrieving computers where specified user is in local admin group?

I have windows domain network, i have about 3000 hosts in there. I would like to just check the info which of those hosts having specified technical user account in their local admin groups. I am not that great at power shell, though I know the base things.
I belive that I have to make a list of all hosts across several subnets I have and then run a script that will try to log on those hosts with looking account credentials.
What could be the best solution?
There is a very detailed post on TechNet about listing all computers in domain.
And here's the WMI query part (PowerShell, $aComputerList is a list of computer names):
foreach ($sComputerName in $aComputerList) {
$sUserPattern = 'Win32_UserAccount.Domain="domainname",Name="username"'
$sGroupPattern = 'Win32_Group.Domain="{0}",Name="Administrators"' -f $sComputerName
$oResult = Get-WmiObject -ComputerName $sComputerName -Class Win32_GroupUser | `
Where-Object {
($_.groupcomponent -match $sGroupPattern) -and `
($_.partcomponent -match $sUserPattern)
}
[Bool]$oResult
}
The hard part is that some computers probably won't be reachable (if they're turned off for instance). So you'll need to run your script several times and remove computers from the list as you get responses from them.

PowerShell Script Running as a Service Behaves Strangely

PowerShell Script Running as a Service Behaves Strangely
The Project:
Create a background process that determines if the on board network card is connected. If it is connected, disable the wireless network card. When the onboard network card is not connected, re-enable the wireless card.
Why:
Users hot-dock all the time, getting funky routing tables OR get bound to the wrong DNS servers. When they attempt to access a local resource, say printers, they aren’t able to and then are in my cube (they would file a ticket, but that too would be a local resource). Trying to convince users to disable their own wireless (via switch on laptop) or not hot dock has met with limited success.
The Problem:
The PowerShell script below does run, and does work under my testing conditions. Likely under most testing conditions as the code and wmi queries are pretty generic. Running the script manually yields the expected results, HOWEVER running the script as a service via the only method I could find, srvany.exe, yielded unexpected results and “broke stuff”.
Details:
Running the script as a service, via srvany.exe, works ONCE. When the loop comes back around to test the network connection or tries the method to enable or disable it. The errors indicate that “get-wmiobject” is not a proper Cmdlet. Huh? It works, manually, it works once, but a second time after it disabled the wireless network card it does not. Worse yet MY shell , outside of the service, suddenly can’t do a get-wmiobject, until…. until you go into Device Manager and re-enable the wireless network card yourself.
Debugging attempts:
I rewrote the script and cleaned it up a little to allow for it to get the objects outside of the Do While loop. Nothing changed, but I left the script that way as it seems cleaner anyhow. I enabled “Interact with Desktop” in the service properties and sure enough you can see the script trying to work and getting the before mentioned errors.
Please help. Again the object here is to run a background process, one with enough privileges in Vista or 7 to disable and enable the wireless network card.
#***********************************************************************
# "switch-wifi-srv.ps1"
# This script attempts to identify if a wired network card is in use if
# one is, the Wireless network card is disabled, until the wired network
# card is no longer in use.
#
# Written by Aaron Wurthmann - aaron (AT) wurthmann (DOT) com
#
# 2010.02.10 ver 2 (Service Version)
# If you edit please keep my name or at the very least original author's.
# As of this writing I am unsure if script will work with all scenarios,
# however it has worked for me on Dell laptops running Windows 7 x64.
# -----------------------------------------------------------------------
# This script comes with ABSOLUTELY NO WARRANTY.
# You may redistribute copies of the script under
# the terms of the GNU General Public License.
# -----------------------------------------------------------------------
# Service Installation:
# Aquire and install the Windows 2003 Resource Kit OR the srvany.exe.
# Use sc.exe and srvany.exe to create a service....
# sc create SwitchWifiAuto binPath= "C:\Program Files (x86)\Windows Resource Kits\Tools\srvany.exe" DisplayName= "Switch Wifi Automatically"
# Edit registry entry for SwitchWifiAuto, add a key and a string value...
# HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\services\SwitchWifiAuto\Parameters]
# "Application"="C:\\Windows\\System32\\WindowsPowerShell\\v1.0\\powershell.exe -ExecutionPolicy RemoteSigned -File C:\\SwitchWifiAuto\\switch-wifi-srv.ps1"
#************************************************************************
$state=""
$wireStatus=""
$wifiStatus=""
# Get Wired and Wireless Card Objects
$objWire=get-wmiobject -class win32_networkadapter -namespace root\CIMV2 | Where-Object {$_.Name -notmatch "Wireless" -and $_.Name -notmatch "Virtual" -and $_.PhysicalAdapter -eq "True"}
$objWifi=get-wmiobject -class win32_networkadapter -namespace root\CIMV2 | where-object {$_.Name -match "Wireless"}
# Get Name of Service to be Used in totally useless Do While Loop
$objService=get-service -display "Switch Wifi Automatically"
# Begin Do While Loop
Do {
# Get status of wired network card. If enabled and connected set $state to Disable (which will later Disable the Wifi network card)
[string]$wireStatus=$objWire | % {$_.NetEnabled}
if($wireStatus -eq "True") {
$state="Disable"
}
# Get Status of wireless card.
if($objWifi){
[string]$wifiStatus=$objWifi | % {$_.NetEnabled}
# If $state is not set to disable and if the wireless card is currently disabled, enable it.
if($state -ne "Disable") {
if($wifiStatus -eq "False") {
Out-Null -InputOject ($objWifi | % {$_.Enable()})
}
# If $state is set to Disable and if wireless card is currently enabled, disable it.
} else {
if($wifiStatus -eq "True") {
Out-Null -InputOject ($objWifi | % {$_.Disable()})
}
}
}
# Reset Checked Variables for good measure
$state=""
$wireStatus=""
$wifiStatus=""
# Sleep for 120 seconds (two minutes)
Start-Sleep -s 120
# Continuing looping (do while) until the service is not running.
# This is of course technically useless as when the service is not running neither is the script to check if the service is not running.
# I made it this way however because I don't like infinite loops and I thought it would be funny to it this way instead of while $var=0
} while ($objService.Status -eq "Running")
Try to remove any output. Service don't have stdout stream. And when the buffer is full strange thing happens. Just a guess ( I never used powershell ).
Debugging attempts: I rewrote the script and cleaned it up a little to
allow for it to get the objects outside of the Do While loop.
You need to include these within the loop or you will not get updated values and the loop will do nothing.

Resources