List all services in PowerShell - powershell

There are some services in Windows (such as http and USBStor) which are not listed when you view Services, or when running the Get-Service cmdlet. What is the simplest way to list all services, even the hidden or unlisted ones?
For example, the http and USBStor services are not enumerated when listing services, but they can be accessed directly by name:
PS C:\Windows\System32> Get-Service | Where-Object {"http","usbstor","spooler" -contains $_.Name}
Status Name DisplayName
------ ---- -----------
Running Spooler Print Spooler
PS C:\Windows\System32> Get-Service "http","usbstor","spooler"
Status Name DisplayName
------ ---- -----------
Running http HTTP Service
Running spooler Print Spooler
Stopped usbstor USB Mass Storage Driver

This might not be the most elegant way of getting all the services (hidden per say), but this will give you all the services along with ones these are dependent on.
Get-Service -RequiredServices | select -Unique DisplayName | ? {$_.DisplayName -like "Http*" }

Try 'Get-CimInstance'.
Such functions (Get-Service) delivered by Microsoft rely on and use CIM/Win32 classes.
(Get-Service only shows Windows services. 'HTTP' is a system driver.)
Get-CimInstance 'CIM_Service'

Related

How to resolve latest DNS CName results via powershell

I am trying to resolve the latest DNS CName using the following powershell script. However due to the DNS server caching, I am getting the cached host name which is not the latest CName.
Is there anyway to avoid this and get the latest results? (as in digwebinterface.com)
Afterwards I am invoking a third party DNS management API, which will modify or create DNS CName mapping. For this I need the latest dns data.
#resolve the dns host name
$resolvedCName = Resolve-DnsName -Name $vanityHostName -DnsOnly -Type CNAME |
Select-Object -First 1 -Property Name,NameHost
write-host $resolvedCName.NameHost
This is not a PowerShell issue or error. Its an environment condition.
Why are you not just clearing the cache as part of what you are doing?
Are you saying, that the DnsClientCache cmdlets or Ipconfig -FlushDNS are not giving you what you are after?
The Clear-DnsClientCache cmdlet deletes all the contents of the DNS client cache. Running this cmdlet is equivalent to running ipconfig /flushdns.
Get-Command -Name Clear-DnsClientCache | Format-Table -AutoSize
<#
CommandType Name Version Source
----------- ---- ------- ------
Function Clear-DnsClientCache 1.0.0.0 DnsClient
#>
# get function / cmdlet details
Get-Command -Name Clear-DnsClientCache -Syntax
(Get-Command -Name Clear-DnsClientCache).Parameters.Keys
Get-help -Name Clear-DnsClientCache -Full
Get-help -Name Clear-DnsClientCache -Online
Get-help -Name Clear-DnsClientCache -Examples
ipconfig /?
<#
USAGE:
ipconfig [/allcompartments] [/? | /all |
/renew [adapter] | /release [adapter] |
/renew6 [adapter] | /release6 [adapter] |
/flushdns | /displaydns | /registerdns |
/showclassid adapter |
/setclassid adapter [classid] |
/showclassid6 adapter |
/setclassid6 adapter [classid] ]
where
adapter Connection name
(wildcard characters * and ? allowed, see examples)
Options:
...
/flushdns Purges the DNS Resolver cache.
/registerdns Refreshes all DHCP leases and re-registers DNS names
…
#>
Apologies for the late response, finally I decided to go with the DNS solution (Ansible Tower) API to get the CName for the hostname.
Powershell Resolve-DnsName -DnsOnly take some time to propagate the DNS. However my release pipeline expect the propagation to be done within few minutes. It's actually doing couple of changes to the host name.
The use of -DnsOnly switch will resolves the query using only the DNS protocol. Even this takes some time to resolve latest DNS results. Therefore I had to go with the API and it worked without any latency issues.
For recurring DNS testing that tou need to have change when the responsible nMe server changez the address, query the responsible namd server directly.
Clearing the client side cache will not effect Resolve-DNSName ] as it id an NSLookup equivalent and so queries the remote server directly instead of using the host's normal resolver mechanism.
So, you should locate the name servers for $VanityHostName uding a half dozen methods, such as arin or dnstoolbox, then specify the name servers for the site as the server in your query as below (4.2.2.2 is a placeholder for the address of the sites' s name server.)
#resolve the dns host name
$resolvedCName = Resolve-DnsName -Name $vanityHostName -DnsOnly -Type CNAME -Server '4.2.2.2' | Select-Object -First 1 -Property Name,NameHost
write-host $resolvedCName.NameHost

VMWare PowerCLI Get DiskUsage of powered off vm's

I'm creating a script that gets all vm's and shows the DiskSpace. THe Problem is, that if a vm is powered off, it won't show the uesed Space of a disk.
Here are two examples: First one with an VM that is powered on:
PowerCLI C:\> Get-VM sluwv0039
Name PowerState Num CPUs MemoryGB
---- ---------- -------- --------
sluwv0039 PoweredOn 2 4.000
PowerCLI C:\> $VM = Get-VM sluwv0039
PowerCLI C:\> $VM.guest.disks
CapacityGB FreeSpaceGB Path
---------- ----------- ----
49.997 5.417 C:\
Example two where the VM is powered off:
PowerCLI C:\> Get-VM sluwv0012
Name PowerState Num CPUs MemoryGB
---- ---------- -------- --------
sluwv0012 PoweredOff 4 8.000
PowerCLI C:\> $VM = Get-VM sluwv0012
PowerCLI C:\> $VM.guest.disks
PowerCLI C:\>
Note: The Last line is the output. There is no "CapacityGB" etc.
Correct, that property is reading from the guest file system to see how much space is left on the partition. In your case, the C:\ drive. If the VM is off, there's no way for PowerCLI to find that property.
Alternatively, you could look at the $vm.ExtensionData.Summary.Storage properties and do some rough conversions. Note: the output of those are in byte, so you'll want to convert them to GB. Example: $tempVM.ExtensionData.Summary.Storage.Committed / 1GB
It won't be exact, but it will be better than no output at all.
here is example of script to show vm specification:
Get-Vm | Select-Object Name,PowerState,VMHost,NumCPU,MemoryGB,ProvisionedSpaceGB,#{N="HostName";E={#($.guest.HostName)}},#{N="Gateway";E={#($.ExtensionData.Guest.IpStack.IpRouteConfig.IpRoute.Gateway.IpAddress[0])}},#{N="DNS";E={$.ExtensionData.Guest.IpStack.DnsConfig.IpAddress}},#{N="IPAddress";E={#($.guest.IPAddress -like "192.168.*")}},#{N="Nics";E={#($.guest.Nics)}},#{N="Datastore";E={#($ | Get-DataStore)}},#{N="Disks";E={#($.guest.Disks)}},Version,#{N="State";E={#($.guest.State)}},#{N="OS";E={#($_.guest.OSFullName)}}
the sample output is like this:
Name State VMHost NumCpu MemoryGB PowerState ProvisionedSpaceGB Version IPAddress HostName OS Nics Disks VMwareTools Gateway DNS
test Running 192.168.32.100 2 1 PoweredOn 43.1085147 v8 192.168.122.1 Elenoon Ubuntu Linux (64-bit) Network adapter 1:VM Network Network adapter 2:local : : Capacity:17167286272, FreeSpace:14212493312, Path:/ Capacity:15188623360, FreeSpace:15154872320, Path:/media/files Capacity:10724835328, FreeSpace:10672824320, Path:/var/log Capacity:973770752, FreeSpace:690139136, Path:/boot guestToolsRunning 127.0.0.1
hope to be useful ;)

Getting Azure VM OS name using PowerShell

I have been trying to get the VM OS name from Microsoft Azure using PowerShell.
I think I am very close to the solution but I don't know where I'm going wrong.
This is the command that I am using to get the VM details:
Get-AzureRmVM -ResourceGroupName TEST -Name VF-Test1 | Select OsType
The answer I get is just blank.
When running the following command:
Get-AzureRmVM -ResourceGroupName TEST -Name VF-Test1
I get all the details that belong to that VM.
The osType property lives inside $_.StorageProfile.osDisk
Get-AzureRmVM -ResourceGroupName TEST -Name VMNAME |
Format-Table Name, #{l='osType';e={$_.StorageProfile.osDisk.osType}}
Name osType
------ ------
VMNAME Windows
Use https://resources.azure.com to explore the object representation when in doubt, or pipe to Show-Object, like i did below.
You can get resource groups' VMs by Get-AzureRmVM and classic VMs by Get-AzureVM. Both of the returning values of the two cmdlets contain OS type properties but in different paths.
For the cmdlet Get-AzureRmVM, the OS type property path is $vm.StorageProfile.OsDisk.OsType
For the cmdlet Get-AzureVM, the OS type property path is $vm.VM.OSVirtualHardDisk.OS
There exists a sample code about fetching Azure VM OS Type here: https://gallery.technet.microsoft.com/How-to-retrieve-Azure-5a3d3751
Get-AzVM -name SERVERNAME | select name, #{n="OS";E={$_.StorageProfile.OsDisk.OsType}}, #{n="Offer";E={$_.StorageProfile.ImageReference.offer}} , #{n="SKU";E={$_.StorageProfile.ImageReference.sku}}, #{n="Publisher";E={$_.StorageProfile.ImageReference.Publisher}}
RESULT:

Not Seeing Expected Output When Capturing Results of Command to Variable and Writing to Console in Powershell 2.0

I'm trying to understand what's going on here in Powershell (v2.0, if important). I'm capturing the results of a command to a variable and when I write it to the console, I'm not getting the results I expect. Everything but the output is functioning as expected.
This is an MCVE that acts in the same way as a script that I wrote. I've just broken it down so that I can provide commentary on what's happening, where it's not working the way I think it should work, and what I think may be happening.
In this first snippet, I'm validating the status of the service MyService
on computer svr0123. This gives the output that I'm expecting.
PS C:\Temp> Get-Service -Name MyService -CN svr0123
Status Name DisplayName
------ ---- -----------
Stopped MyService My_Service_Display_Name
PS C:\Temp>
In this second snippet, I'm doing the same, only assigning the output to
$results with the intention of restarting any stopped services. Again, this
gives the output I'm expecting.
PS C:\Temp> $results = Get-Service -Name MyService -CN svr0123
PS C:\Temp> Write-Output $results
Status Name DisplayName
------ ---- -----------
Stopped MyService My_Service_Display_Name
PS C:\Temp>
Finally, I'm restarting the service, then writing the contents of $results
to the console. This does not function as expected. I would anticipate
that the contents of $results would be the same as the previous two outputs,
but instead I get:
PS C:\Temp> $results | Where { $_.Status -eq "Stopped" } | Set-Service -Status Running
PS C:\Temp> Write-Output $results
Status Name DisplayName
------ ---- -----------
Running MyService My_Service_Display_Name
PS C:\Temp>
This is incorrect unless each time I reference the contents of
$results it is calling the Get-Service command again, which is counterintuitive. If that's the case, it
appears that I'm not storing the output of the command, but rather I'm
storing an alias to the command. If I write the contents of $results to the console before doing the restart, everything outputs as expected.
This is a trivial fix, but I'm trying to understand the "Why" behind what I'm observing. My questions are:
Is this, in fact, what is occurring? Where in the Powershell documentation
can I learn more about this?
If this is what is occurring, is there a way that I can just store the
output so that I'm not incurring multiple calls? It's trivial in this
case, but my script will be used on a busy network and may at times have
to query hundreds of servers in a given run.
When you call Get-Service -Name MyService -CN svr0123 it is returning a ServiceController object, not just the text of the output.
So, when you call this line:
$results = Get-Service -Name MyService -CN svr0123
$results is not just a string variable containing the output of the command. It is actually a variable of type ServiceContoller.
Run this to see:
$results.GetType()
You will get this:
IsPublic IsSerial Name BaseType
-------- -------- ---- --------
True False ServiceController System.ComponentModel.Component
So, the second time you execute Write-Output $results, the service has been started and the $results variable is displaying the current status of the service.
I think it does not re-call Get-Service when you display the service object. I think the $service object has an internal state which is a text value, and when you pipe it to Set-Service that state value gets changed as well as the service being started/stopped.
Since trying to change it directly with $service.Status = "Running" generates an error because the property is read-only, this change could be happening through the service object's own $service.Start() and $service.Stop() methods found from $service | get-member
Supporting evidence from some quick tests:
I $service = get-service testsvc; $service and see the state is Running, then I go to Control Panel and stop the service there, and the $service state does not change.
I call $service.Start() directly to restart the service, and I get an exception (possibly because my PowerShell is not running as an Admin) so the service does not actually start running, however $service.Status does change (incorrectly) to say the service is running.
This way I get a disconnect between the reported status and the actual status is convincing me, and the way it seems implausible/impractical for every object to "know" how it was generated and arbitrarily re-run that code (what if it was a 30 minute query to generate it?) but I don't know for sure what the interactions are.

qwinsta /server:somesrv equivalent in Powershell?

When I run the qwinsta /server:somesrv command in cmd I can get a listing of all the current RDP sessions that are logged into a particular Windows server.
SESSIONNAME USERNAME ID STATE TYPE DEVICE
console 0 Conn wdcon
rdp-tcp 65536 Listen rdpwd
rdp-tcp#594 tom1 1 Active rdpwd
rdp-tcp#595 bob1 2 Active rdpwd
Is it possible to get a list like this on a remote server from Powershell so that the data can be used elsewhere?
There are multiple alternatives:
Use the Terminal Services PowerShell Module. Easy solution.
Writing a powershell wrapper that parses the output of qwinsta to objects. Easy solution. See example below
Use the Cassia.DLL .Net wrapper to access the native APIs that qwinsta runs behind the scene. This is the class that the TS Module uses. More difficult, but will have the benefit of being customized to your needs.
Go crazy and use the Native Methods that Cassia.DLL accesses using P/Invoke (wtsapi32.dll, kernel32.dll, winsta.dll). Hard and overcomplicated.
PowerShell-wrapper for qwinsta
function Get-TSSessions {
param(
$ComputerName = "localhost"
)
qwinsta /server:$ComputerName |
#Parse output
ForEach-Object {
$_.Trim() -replace "\s+",","
} |
#Convert to objects
ConvertFrom-Csv
}
Get-TSSessions -ComputerName "localhost" | ft -AutoSize
SESSIONNAME USERNAME ID STATE TYPE DEVICE
----------- -------- -- ----- ---- ------
services 0 Disc
console Frode 1 Active
rdp-tcp 65537 Listen
#This is objects, so we can manipulate the results to get the info we want. Active sessions only:
Get-TSSessions -ComputerName "localhost" | ? { $_.State -eq 'Active' } | ft -AutoSize SessionName, UserName, ID
SESSIONNAME USERNAME ID
----------- -------- --
console Frode 1
I used to use Terminal Services PowerShell Module (now in codeplex archive), but it was two years ago. I can't put my hand on it, but it also exists a function on gitshub or another site that embeded QWinsta/RmWinsta.