How to retrieve xenstore parameters from WMI interface - powershell

I'm trying to retrieve some parameters from xenstore using WMI (specifically, I was hoping to use this script to change a VM IP address after it's created).
According to this article, it seems like I should just be able to do something like:
From the xenserver CLI:
xe vm-param-set uuid=e66660e9-85e1-1f99-3229-1dfa7d1065a8 xenstore-data:data/TempValue=test
then in a powershell script:
$base = gwmi -n root\wmi -cl CitrixXenStoreBase
$sid = $base.AddSession("MyNewSession")
$session = gwmi -n root\wmi -q "select * from CitrixXenStoreSession where SessionId=$($sid.SessionId)"
$output = $session.GetValue("data/TempValue").value
log "$output"
But that doesn't seem to retrieve the value that I expect.
One thing I noticed was if I set the value from a powershell script, it seems to consistently retrieve the value when I run the previous script:
$base = gwmi -n root\wmi -cl CitrixXenStoreBase
$sid = $base.AddSession("MyNewSession")
$session = gwmi -n root\wmi -q "select * from CitrixXenStoreSession where SessionId=$($sid.SessionId)"
$session.SetValue("data/TempValue","This is a string")
It seems to retain the set value across sessions, but when I go back to the CLI and attempt to find the value, I get nothing:
xe vm-param-list uuid=e66660e9-85e1-1f99-3229-1dfa7d1065a8 | grep TempValue
So what it boils down to is that I'd like to either:
Know how to retrieve a xenstore parameter in a WMI script after executing the xe vm-param-set command.
Know how to set a parameter in the xenserver CLI in the same way that $session.SetValue works in the above example.

Nevermind, looks like this was user error on my end. I was setting the values after the VM was already started. Looks like the parameters have to be set before the VM starts (or the VM should be restarted).

Related

Using Powershell to find last step run from an SQL agent job

I have a powershell script that provides SQL Agent Job information. The script is meant to monitor the jobs and tell me if they failed the last time they ran. However i also want to know which was the last run step. and i can't seem to figure out how.
I am querying the Sql server mangement object, because it needs to be usable on multiple remote servers (remote connections) and i wish to avoid running SQL scripts.
Keep in mind i'm rather new to powershell.
This is the code i have so far: And i have loaded the SMO libraries, i just didn't show it the copied script.
## Get Jobstep Class SMO
Push-Location; Import-Module SQLPS -DisableNameChecking; Pop-Location;
$JobStep = New-Object microsoft.sqlserver.management.smo.agent.jobstep
## Run the select from the local SQL server management objects
$SQLSvr = "."
$MySQLObject = new-object Microsoft.SqlServer.Management.Smo.Server `
$SQLSvr;;
$Select = ($MySQLObject.JobServer.jobs) `
| Select Name, isEnabled, `
lastRunDate, lastRunOutCome, NextRunDate `
| Where-Object {$_.LastRunDate -ge ((Get-Date).adddays(-2)) } `
| ft -AutoSize;
$Select
The push-location section is meant to get the correct smo class for selecting the job step (unsure if it is right), however i haven't added anything from it.
Now the script does work, i get no errors and i get returned the overall information i want, but i cannot figure out how to add the jobstep - and i have consulted google. I'm well aware that i need to add more to the select, but what is the issue for me. So, how do i extract the last run job step from SQL Agent job, using the SMO, and add it to the above script?
You can use the SqlServer module from the PowerShell Gallery (Install-Module SqlServer), and then something like:
$h = Get-SqlAgentJobHistory -ServerInstance servername -JobName jobname
$h[0] will give you the last step ran.
This will give you the result in the format you wanted:
Get-SqlAgentJob -ServerInstance servername |
Where-Object {$_.LastRunDate -ge ((Get-Date).AddDays(-2))} | ForEach-Object {
$h = Get-SqlAgentJobHistory -ServerInstance servername -JobName $_.Name
[PSCustomObject]#{
Name = $_.Name
IsEnabled = $_.IsEnabled
LastRunDate = $_.LastRunDate
LastRunOutcome = $_.LastRunOutcome
NextRunDate = $_.NextRunDate
LastRunStep = $h[0].StepName
}
}

How to run VMware commands from remote scripts on windows

Have a local basic Powershell form for searching and creating VMware virtual machines.
Using new powershell powerCLI module, as described in link
Let's take Get-VM for example:
LOGIC: Type a certain string in TextBox > click search > prints VM's status/parameters in the form
The problem is, I can't execute Get-VM straight away from the script, but first have to connect using Connect-VIServer command and only than Get-VM will work
Is there any way to do it from the script? Something similar to -m flag of commands plink or putty.
Like: Connect-VIServer -server testvc -flagForExample "commands_list.txt"
Yes, you can. Before providing an immediate answer I'd like to explain what is actually happening.
When you call Connect-VIServer the command sets the value of the variable $DefaultVIServer behind the scenes, which is later used by other cmdlets (such as Get-VM).
However, the Get-VM documentation states that there is a Server parameter available. Which means that you can store your server connection in a variable and then pass it to the Get-VM cmdlet.
Here's a pseudo-code example:
$server = Connect-VIServer -server testvc
Get-VM -Server $server
Furthermore, the Get-VM supports an array of servers, so theoretically you can run the cmdlet on multiple servers at once. For example:
$server1 = Connect-VIServer -server testvc
$server2 = Connect-VIServer -server testvc2
Get-VM -Server #($server1, $server2)

Running Command as Administrator from a SYSTEM Process

So I need to clear a user's run dialog history which I can do perfectly fine with "reg delete HKEY_CURRENT_USER\Software\Windows etc..." from an elevated powershell window on the logged in user's machine, but what I'm looking to do is that same command but from a SYSTEM powershell process. I have already used psexec to create a powershell window which runs as SYSTEM, but because you can't just use HKEY_CURRENT_USER as SYSTEM with the same results, I am finding it quite difficult. If I could just run that command but as username\Administrator then I wouldn't have this problem.
Also to note, if I can somehow grab the username of the logged on user (from SYSTEM still) in one line in plain text (with no other output in sight), then I can store the username in a variable and convert that to an SID and use HKEY_USERS instead.
P.S. Don't ask why I'm running powershell as SYSTEM, I know what I'm doing :D
you can use get-process under the system context powershell and filter where explorer.exe process is running, get the account it is running under then use to convert to SID and go through the registry.
something like this assuming only 1 explorer.exe process is running which is the norm on windows client OS.
$proc = Get-CimInstance Win32_Process -Filter "name = 'explorer.exe'"
$owner = Invoke-CimMethod -InputObject $proc -MethodName GetOwner
$username = $owner.user
$username will contain the user, $owner will also contain domain and a few other things.
to convert to sid
$objUser = New-Object System.Security.Principal.NTAccount($owner.Domain, $owner.User)
$strSID = $objUser.Translate([System.Security.Principal.SecurityIdentifier])
$strSID.Value

logged on users in array or object (powershell, command line)

I have few Windows Server 2012 R2 with RDS installed and I need to have function which returns array or object with users and their session IDs on specified server. I need to run this function with non-admin permissions. On the session hosts I ran this command:
wmic /namespace:\\root\CIMV2\TerminalServices PATH Win32_TSPermissionsSetting WHERE (TerminalName ="RDP-Tcp") CALL AddAccount "domain\group",2
...so the users have elevated permissions and now they can use RDS shadowing through command line. The ID which I need is the session ID which I can get for example from command "quser". The best solution will be if I will have function which returns array (with logged on users on the specific server) like this (or something similar, maybe object):
LOGIN ID
user1 -> 3
user2 -> 4
user3 -> 5
I don't know if this function or these commands will solve my problem, however I tried them and this was the result:
I tried this:
http://gallery.technet.microsoft.com/scriptcenter/Get-UserSessions-Parse-b4c97837
but the command returns nothing.
This command:
WMIC /NODE:<COMPUTERNAME> COMPUTERSYSTEM GET USERNAME
returns only "UserName" and this:
Get-WmiObject Win32_ComputerSystem | Select UserName
..returns only "UserName" with underlines. I tried a lot of variations of WMI commands, but with similar results.
There's probably a half dozen scripts in various repositories around the 'net to do that.
I use this one:
http://gallery.technet.microsoft.com/scriptcenter/0e43993a-895a-4afe-a2b2-045a5146048a
gwmi -query "Select * from Win32_LogonSession where LogonType = 2" |
% {
$user = $_
gwmi -query "Associators of {$user} Where AssocClass=Win32_LoggedOnUser" | select *
}

Windows PowerShell authentication

I am running PowerShell 1.0 under Windows XP, attempting to connect to machines running XP, Vista, and Server 2003 with the following command:
gwmi -cl Win32_OperatingSystem -co COMPUTER -n "root\CIMV2" -cr DOMAIN\ADMIN
This returns an error. "Exception retrieving members: Access is denied.".
gwmi -cl Win32_OperatingSystem -co COMPUTER -cr DOMAIN\ADMIN
This works.
Firewall and DCOM services are configured properly, otherwise neither command would not run.
I have tried the first command with credentials set to COMPUTER's local administrator, same error.
I can run the first command against localhost, no error.
$q = "Select * from Win32_OperatingSystem"
$y = [WmiSearcher] $q
$y.Scope.Path = "\\COMPUTER\root\cimv2"
$y.Scope.Options.Authentication = 6
$os = $y.Get()
also fails. The administrator group on COMPUTER has the appropriate permissions according to this Microsoft KB article.
We recently rolled out a WSUS server, pushing out a ton of miscellaneous Windows Updates to our systems. Are any updates known to break WMI like this?
I wonder if the remote side is requiring an encrypted connection for this particular namespace.
See if this approach works for you:
$q = "Select * from Win32_OperatingSystem"
$y = [WmiSearcher] $q
$y.Scope.Path = "\\<remote_computer_name>\root\cimv2"
$y.Scope.Options.Authentication = 6
$os = $y.Get()
Here is a link related to this issue.