Powershell: Re-create RDS Remote Apps by Looping? - powershell

I'm stumped. I can usually take the output of one powershell command and use it as the input to another powershell command. For example:
Get-Mailbox | Set-Mailbox -MaxSendSize 40MB
This will loop through every mailbox and then set the maximum send size to 40 MB in Exchange 2007.
...but the same doesn't work with get-rdremoteapp and new-rdremoteapp.
Get-RDRemoteApp | new-rdremoteapp -collectionname APPSNEW -connectionbroker edge-1.mydom.local
The goal of this command is that we are preparing to Migrate from a Windows 2012 RDS environment on virtual servers to a Windows 2012 R2 environment on physical servers.
On the virtual 'edge' server, I should be able to get all the RD Remote Apps, loop through them, and then use the 'new-rdremoteapp' command to create them on the new 'edge-1' server.
What actually happens is the command runs and creates the 1st remote app, then exits without an error. It doesn't process the apps in the list.
I think I need to use foreach-object, but after reading the docs and playing around, I can't seem to get it to work.

I couldn't find an easy out. I had to specify a bunch of parameters like so:
Get-RDRemoteApp | foreach-object -process {new-rdremoteapp -collectionname APPSNEW -connectionbroker edge-1.mydom.local -displayname $_.displayname -filepath $_.filepath -alias $_.alias -commandlinesetting $_.commandlinesetting -usergroups $_.usergroups}
Time to find a job that has more bash scripting... ;)

Related

Is there a way to find which user run what application on a server using Powershell

I am trying to find a way to find out who has ran an application (for example SQL) on a server, just to get some idea.
I tried Get-Process but this doesn't give me historic information, I want to get historical information
Get-Process -IncludeUserName *
what I want the return resule is "name of application", "user who ran it" and the last datetime it was ran by that user'
As for ...
I am trying to find a way to find out who has ran an application (for
example SQL) on a server, just to get some idea.
What you are asking for here is software metering.
SQL is a service that is always running once it is installed, so, no individual user is ever going to be running it. So, that is a bad example. MS Word for example would be a better example.
Yet there is nothing native in PowerShell that does this, software metering, but of course PowerShell can look at event logs. Yet if your auditing is not setup correctly then it's moot. This is better for a software metering tool, and there are several out there. So, why try and reinvent the wheel.
As for ...
I tried Get-Process but this doesn't give me historic information, I
want to get historical information
That is not what a process is nor what Get-Process is for. It, Get-Process only checks for and lists whatever process is currently running, regardless of what/who launched it.
As for...
what I want the return resule is "name of application", "user who ran
it" and the last datetime it was ran by that user'
As long as the process is running, you can get this, with that cmdlet.
However, what are you trying to accomplish by this?
Again, there are purpose built tools to meter software use.
https://learn.microsoft.com/en-us/sccm/apps/deploy-use/monitor-app-usage-with-software-metering
If you must go down this reinvent the wheel road, using scripting, then you need a task watcher on the target machines, which watches for the WinWord process to appear.
Get-Process -IncludeUserName |
Where ProcessName -EQ 'Winword'
... you then write those results to a file or database or your own event log each time you see that process.
Use PowerShell to Create and to Use a New Event Log
New-EventLog -LogName ScriptingGuys -Source scripts
When the command runs, no output appears to the Windows PowerShell console. To ensure the command actually created a new event log, I use
the Get-EventLog cmdlet with the –List parameter. Here is the command
and the associated output.
Write-EventLog -LogName ScriptingGuys -Source scripts -Message “Dude, it works … COOL!” -EventId 0 -EntryType information
Or just to a file
Get-Process -IncludeUserName |
Where ProcessName -EQ 'Winword' |
Select-Object -Property Name, StartTime, Username |
Export-Csv -Path 'F:\Temp\AppLaunchLog.csv' -Append
Import-Csv -Path 'F:\Temp\AppLaunchLog.csv'
# Results
Name StartTime UserName
---- --------- --------
WINWORD 5/23/2019 9:02:53 PM WS01\LabUser001

Looking for a Powershell Script to check if Volume Shadow Copy is enabled

Sorry for asking, new in PowerShell. Looking for a Powershell Script to check if Volume Shadow Copy is enabled.
Couldn't find any useful and functional script.
Where did you look?
There are a number samples of these all over the web.
For example, using the script downloadable from here:
Get Shadow Copy Statistics
If you use Shadow Copies of Shared Folders (Previous Versions), this
script may help you keep on eye on how much history you have, the
average snapshot size, whether you are hitting storage area limits or
the 64 shadow copies per volume limit.
https://gallery.technet.microsoft.com/scriptcenter/Get-Shadow-Copy-Statistics-79e05a57
You can use it's example to get stats of such items. Meaning, if you get any results, then of course it's enabled.
#Query the local machine
.\Get-ShadowCopyStats.ps1 -ServerName .
#Query a remote machine
.\Get-ShadowCopyStats.ps1 -ServerName FS01
#Query multiple remote machines by passing an array
.\Get-ShadowCopyStats.ps1 -ServerName FS01,FS02
#Since it's the first parameter, you don't have to include -ServerName in the command:
.\Get-ShadowCopyStats.ps1 FS01,FS02
#Query multiple remote machines by passing them to the script down the pipeline
"FS01","FS02" | .\Get-ShadowCopyStats.ps1
Get-ADComputer -Filter * -SearchBase "OU=Servers,DC=company,DC=tld" | .\Get-ShadowCopyStats.ps1 -ShowAllVolumes | Tee-Object -Variable ShadowCopyStats
$ShadowCopyStats | Select * | Export-Csv -NoTypeInformation .\ShadowCopyStats.csv
Or this one...
Get Remote Shadow Volume Information With Powershell
Gather the remote shadow volume information for one or more systems
using wmi, alternate credentials, and multiple runspaces. Function
supports custom timeout parameters in case of wmi problems and returns
shadow volume information, shadow copies, their providers, and
settings.
https://gallery.technet.microsoft.com/scriptcenter/Get-Remote-Shadow-Volume-e5a72619
RemoteShadowCopyInformation -ComputerName 'Server2' -Credential $cred).ShadowCopyVolumes
when the shadowcopy is enabled, there will be a scheduled task created
$allTasks = Get-ScheduledTask
foreach ($task in $allTasks) {
if ($task.TaskName.Contains("ShadowCopyVolume")) {
#get volumeid & drive letter which shadowcopy is enabled
$allVolumes = Get-Volume
foreach ($volume in $allVolumes) {
if ($volume.ObjectId.Contains(($task.TaskName.Split("{")[1]).Split("}")[0])) {
write-host ($volume.driveletter + ":\ is enabled")
}
}
}
}

How to check if a server is running windows 2003 or Windows 2008 by checking its RDP screen, through script?

We have recently acquired a small firm having 1500 servers on which our team doesn't has access as of now although they are in domain. We need to find out how many servers are running Windows 2k3 and how many are Windows 2k8.
I know the RDP screen of both of these versions are different , for example: if we RDP a Win2k3 machine, it gives a warning notice first and once we click Ok, it takes us to the credentials screen , but in case of Win2k8, it directly takes us to Crendentials which is a proof of the OS on the server. Doing this manually for 1500 servers is a time consuming task.
Can we implement this RDP screen logic using a script to find out the Windows OS version.
I can imagine an Algorithm something like that:
Enter server name.
Invoke mstsc for that server
Verify if the dialogue box is a direct prompt for credentials or not?
If so, print Windows 2k8, else 2k3/2k.
If this logic successful on one server, I can use it in a foreach loop for all servers and export in in Excel.
With 1500 servers I'm going to assume that you have an Active Directory in place. In that case you should be able to simply run a query against AD to retrieve the desired information:
Import-Module ActiveDirectory
$server = 'somehostname'
$dc = '...' # domain controller of trusted domain
$fltr = "OperatingSystem -like '*server*'"
Get-ADComputer -Filter $fltr -Property OperatingSystem -Server $dc |
Where-Object { $_.Enabled } |
Select-Object Name, OperatingSystem |
Sort-Object OperatingSystem, Name
Pipe the result into Export-Csv to create a CSV file that you can import into Excel.

Powershell script to check for disconnected sessions that have been disconnected for more then 12 hours

I am trying to write a Powershell script that I can schedule to run at 5am to kick disconnected users off my Citrix servers.
I have found this example:
foreach ($_ in get-content servers.txt) {(gwmi win32_operatingsystem -ComputerName $_).Win32Shutdown(4)}
But am unsure how to edit it to find out if they have been disconnected for more then 12 hours.
If anyone could help that would be awesome.
You could use the Citrix Powershell snapin like below. This script will go through all the sessions in the farm and kick out disconnected ones. You will need to install the Citrix Powershell commands on the box you run this from. Is this for Citrix XenApp 4.5 or higher? Citrix versions below XenApp 4.5 will need to use MFCOM for this but you can still use Powershell.
Add-PSSnapin Citrix.XenApp.Commands
Get-XASession | Where-Object { $_.State -eq "Disconnected" } | Stop-XASession
if the goal is to disconnect users "after" 12 hrs, why dont you implement that in GPO rather than scheduled task?
I usually set GPO to to disconnect user after 2 hrs of idle time, then log out after 30min.

Retrieving real time info from VM's with PowerCLI

I have a couple of lines in a script that are giving me an issue:
Connect-VIServer "test-vcenter.test.com" -User user -Password pass
Get-VM -Name "test-vm" | Get-Stat -Stat cpu.ready.summation -Realtime | Select-Object -First 1 value | Format-List
When running this I receive this as output:
Operation is not valid due to the current state of the object.
At :line:0 char:0
If the second line is run a few seconds after the connection to vCenter is made I receive the output I expect. What I believe is happening is that my connection to vCenter hasn't completed before my second line has started. I am not sure of the best way to wait for or what to check for in a completed connection.
you might try using start-sleep command in PS
http://technet.microsoft.com/en-us/library/ee177002.aspx
however -- as with all "sleep" functions, this isn't necessarily the best way to fix a timing problem as your pushback never may never account for all possible latency issues.
a better solution would be to test for the completion of a command (and I'm not sure how to do that with the VMWare CLI)