Very new to PS - different results when running commands vs .ps1 - powershell

trying to get some basic stuff scripted. When I run some commands in a powershell window I get a nice simple list however if I run a .ps1 file with the same command I get an unnecessarily verbose output. Is there a "less verbose" flag or setting I'm not aware of?
while this issue in particular is likely not tied to the commands I'm using, for reference I am using this command in this instance:
invoke-command -computername $servers -scriptblock {Get-Package -Name PSWindowsUpdate}
EDIT: For future readers - I solved the issue by inserting Select-Object Name as well. This provides a concise list:
invoke-command -computername $servers -scriptblock {get-package -name pswindowsupdate | select-object name}

It doesn't format the same over invoke-command. It's a serialized object now, so the type is different. I usually do
icm $comps { get-package program | select name,version }
You won't even see the output of select-string without extra help:
icm $comps { echo hi | select-string hi | select line }
Those without multiple computers can try invoke-command with localhost at the elevated powershell prompt. All the object properties get dumped because the object's serialized.
invoke-command localhost { get-package 'google chrome' }
PropertyOfSoftwareIdentity : PropertyOfSoftwareIdentity
PSComputerName : localhost
RunspaceId : d843e737-577c-4d04-be21-7ab608694c79
FastPackageReference : {E9AB118B-2341-3DD2-BD45-27B55F5F3802}
ProviderName : msi
Source :
Status : Installed
SearchKey : google chrome
FullPath :
PackageFilename : ?
FromTrustedSource : False
Summary :
SwidTags : {Microsoft.PackageManagement.Packaging.SoftwareIdentity}
CanonicalId : msi:Google Chrome/108.0.5359.99
Metadata : {ProductCode}
SwidTagText : <?xml version="1.0" encoding="utf-16" standalone="yes"?>
<SoftwareIdentity
name="Google Chrome"
version="108.0.5359.99"
versionScheme="multipartnumeric"
tagId="E9AB118B-2341-3DD2-BD45-27B55F5F3802"
xmlns="http://standards.iso.org/iso/19770/-2/2015/schema.xsd">
<Meta
ProductCode="{E9AB118B-2341-3DD2-BD45-27B55F5F3802}" />
</SoftwareIdentity>
Dependencies : {}
IsCorpus :
Name : Google Chrome
Version : 108.0.5359.99
VersionScheme : multipartnumeric
TagVersion :
TagId : E9AB118B-2341-3DD2-BD45-27B55F5F3802
IsPatch :
IsSupplemental :
AppliesToMedia :
Meta : {{ProductCode}}
Links : {}
Entities : {}
Payload :
Evidence :
Culture :
Attributes : {name,version,versionScheme,tagId}

Related

powershell cmdlet doesn't return output properties stated in documentation

I try to write a PowerShell script that outputs open SMB connections on a server so that I can see who's working with the server and with which directory. For that, I found cmdlet get-smbopenfile which looks pretty handy.
The documentation https://learn.microsoft.com/de-de/powershell/module/smbshare/Get-SmbOpenFile?view=windowsserver2022-ps says that the get-smbopenfile output contains properties ClientComputerName and ClientUserName but on my box (Windows Server 2022) the only properties returned are FileId, SessionId and Path. I can't make it return any additional properties.
The documentation seems to be crystal clear on that. What am I missing?
get-smbopenfile | fl * to see everything, otherwise powershell commands use a format file with a default view. All commands are like this. You can still reference any property, even without fl or format-list.
get-smbopenfile | select -first 1 | fl *
SmbInstance : Default
ClientComputerName : [::1]
ClientUserName : AD\SERVER$
ClusterNodeName :
ContinuouslyAvailable : False
Encrypted : False
FileId : 1546188227134
Locks : 0
Path : \eventlog
Permissions : 1180064
ScopeName : *
SessionId : 1546188226562
ShareRelativePath : eventlog
Signed : False
PSComputerName :
CimClass : ROOT/Microsoft/Windows/SMB:MSFT_SmbOpenFile
CimInstanceProperties : {ClientComputerName, ClientUserName, ClusterNodeName, ContinuouslyAvailable...}
CimSystemProperties : Microsoft.Management.Infrastructure.CimSystemProperties

Get-Package command includes xml string - Need to convert to PSObject

Need Windows Update Install Date from Get-Package SwidTagText object. The object is in XML format and everything I have tried to convert doesn't work.
I am trying to switch from WMI because its terribly slow to pull back results.
Tried the ConvertFrom-XML function. Also tried ConvertFrom-String
Get-Package -ProviderName msu | Select-Object *
PropertyOfSoftwareIdentity : PropertyOfSoftwareIdentity
FastPackageReference : Definition Update for Windows Defender Antivirus - KB2267602 (Definition 1.297.486.0)
ProviderName : msu
Source :
Status : Installed
SearchKey :
FullPath : ?
PackageFilename : ?
FromTrustedSource : False
Summary : Install this update to revise the definition files that are used to detect viruses, spyware, and other potentially
unwanted software. Once you have installed this item, it cannot be removed.
SwidTags : {Definition Update for Windows Defender Antivirus - KB2267602 (Definition 1.297.486.0)}
CanonicalId : msu:Definition Update for Windows Defender Antivirus - KB2267602 (Definition 1.297.486.0)
Metadata : {summary,SupportUrl,Date,ResultCode}
SwidTagText : <?xml version="1.0" encoding="utf-16" standalone="yes"?>
<SoftwareIdentity
name="Definition Update for Windows Defender Antivirus - KB2267602 (Definition 1.297.486.0)"
xmlns="http://standards.iso.org/iso/19770/-2/2015/schema.xsd">
<Meta
summary="Install this update to revise the definition files that are used to detect viruses, spyware, and other
potentially unwanted software. Once you have installed this item, it cannot be removed."
SupportUrl="https://go.microsoft.com/fwlink/?LinkId=52661"
Date="7/5/2019 6:17:09 PM"
ResultCode="2" />
</SoftwareIdentity>
Dependencies : {}
IsCorpus :
Name : Definition Update for Windows Defender Antivirus - KB2267602 (Definition 1.297.486.0)
Version :
If you're trying to get the raw dates out of the XML you could do something like this:
$xml = ((Get-Package -ProviderName msu) | Select-Object *).SwidTagText
foreach ($item in $xml)
{
$(
$(
[xml]$item | Select-Object "InnerXml"
).InnerXml | Select-Xml -XPath "//*[#Date]"
).Node.Date
}
This gives you each entry to work with like so:
PS C:\Users\Skuld> $xml[0]
<?xml version="1.0" encoding="utf-16" standalone="yes"?>
<SoftwareIdentity
name="Update for Windows Defender Antivirus antimalware platform - KB4052623
(Version 4.18.1906.3)" xmlns="http://standards.iso.org/iso/19770/-2/2015/schema.xsd">
<Meta
summary="This package will update Windows Defender Antivirus antimalware
platform’s components on the user machine."
SupportUrl="https://go.microsoft.com/fwlink/?linkid=862339"
Date="09/07/2019 10:46:52"
ResultCode="2" />
</SoftwareIdentity>
You then use Select-XML/XPath to pick out the specific date attribute.
My example will give just a list of all the dates, but you could tweak it if you need extra information along side it.
Your code worked and now I make a function that searches for specific items inside the SwidTagText
Truly, Powershell is magical
#Use as much detail as possible. Can't process Arrays yet....
#Example = Get-Package -name "Application Name" | Where-Object { $_.ProviderName -eq "Programs" } | fl *
#Example = Get-Package -name "Application Name" | Where-Object { $_.ProviderName -eq "msi" } | fl *
#Returns any variable from XML SwidTagText
function SwidTagText-XML-Variable ( [string] $PackageName , [string] $XMLName, [string] $PackageType )
{
$PackageObject = Get-Package -name $PackageName | Where-Object { $_.ProviderName -eq $PackageType }
$xml= $PackageObject.SwidTagText
foreach ($item in $xml)
{
$XMLValue = $(
$(
[xml]$item | Select-Object "InnerXml"
).InnerXml | Select-Xml -XPath "//*[#$XMLName]"
).Node.$XMLName
}
return $XMLValue
}
#Example of Ubisoft Program and check for UninstallString
SwidTagText-XML-Variable "*ubisoft*" "UninstallString" "Programs"
So the function will search for an XML item inside the SwidTagText. Parsing and getting XML items from this is so useful

Azure-Runbook: Suppress output of a cmdlet to summary or history

In an Azure-runbook, how can one suppress the output of a cmdlet to show up in the summary or history log?
For instance
Start-AzureVM -Name ...
emits something like
PSComputerName : localhost
PSSourceJobInstanceId : xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx
Id : azure_adm#foo.com
Type : User
Subscriptions : xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx
Tenants : xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx
PSComputerName : localhost
PSSourceJobInstanceId : xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx
OperationDescription : Start-AzureVM
to the summary.
You can use "out-null" in Azure-Runbooks only inside "InlineScript {}"
If you assign the output to a variable, then it will not write it to the console.
Try assigning it to $null like this:
$null = Start-AzureVM -Name ...

WMI:Getting Invalid Class Error when running shell command through another program

I am trying to get PCoIP Statistics which are available through WMI, I use following command for WMIC
wmic path Win32_PerfRawData_TeradiciPerf_PCoIPSessionNetworkStatistics
or with powershell
powershell Get-WmiObject -namespace "root\cimv2" -computername computer01 -class Win32_PerfRawData_TeradiciPerf_PCoIPSessionNetworkStatistics
However when I tried to run either command forked through another process, in this case it was python, and piping the stdout, I am getting Invalid class error like below.
Get-WmiObject : Invalid class
At line:1 char:14
+ Get-WmiObject <<< -namespace root\cimv2 -computername computer01 -class
Win32_PerfRawData_TeradiciPerf_PCoIPSessionNetworkStatistics
+ CategoryInfo : InvalidOperation: (:) [Get-WmiObject], ManagementException
+ FullyQualifiedErrorId : GetWMIManagementException,Microsoft.PowerShell.Commands.GetWmiObjectCommand
if it helps, the output of powershell command through command prompt is
__GENUS : 2
__CLASS : Win32_PerfRawData_TeradiciPerf_PCoIPSessionNetworkS
tatistics
__SUPERCLASS : Win32_PerfRawData
__DYNASTY : CIM_StatisticalInformation
__RELPATH : Win32_PerfRawData_TeradiciPerf_PCoIPSessionNetworkS
tatistics.Name="PCoIP Session"
__PROPERTY_COUNT : 19
__DERIVATION : {Win32_PerfRawData, Win32_Perf, CIM_StatisticalInfo
rmation}
__SERVER : DEMO-VSGA-WS01
__NAMESPACE : rootcimv2
__PATH : \DEMO-VSGA-WS01rootcimv2:Win32_PerfRawData_Terad
iciPerf_PCoIPSessionNetworkStatistics.Name="PCoIP S
ession"
Caption :
Description :
Frequency_Object : 0
Frequency_PerfTime : 10000000
Frequency_Sys100NS : 10000000
Name : PCoIP Session
RoundTripLatencyms : 284
RXBWkbitPersec : 22034
RXBWPeakkbitPersec : 4
RXPacketLossPercent : 112
RXPacketLossPercent_Base : 28805
Timestamp_Object : 0
Timestamp_PerfTime : 299873128867
Timestamp_Sys100NS : 130641888164850000
TXBWActiveLimitkbitPersec : 1832
TXBWkbitPersec : 75615
TXBWLimitkbitPersec : 90000
TXPacketLossPercent : 7
TXPacketLossPercent_Base : 30942
I also tried using python module WMI
hostname = os.getenv('COMPUTERNAME', '')
c = wmi.WMI (hostname, namespace="root\\cimv2")
print c.Win32_PerfRawData_TeradiciPerf_PCoIPSessionNetworkStatistics
I am getting following error
print c.Win32_PerfRawData_TeradiciPerf_PCoIPSessionNetworkStatistics
File "c:\users\ramesh~1\appdata\local\temp\easy_install-tlfipc\WMI-1.4.9-py2.7
-win32.egg.tmp\wmi.py", line 1147, in __getattr__
File "C:\Python27\lib\site-packages\win32com\client\dynamic.py", line 522, in
__getattr__
raise AttributeError("%s.%s" % (self._username_, attr))
AttributeError: winmgmts://computer01/root/cimv2.Win32_PerfRawData_TeradiciP
erf_PCoIPSessionNetworkStatistics
Can this be related to impersonation and authentication level of caller?
UPDATE
I moved the powershell command to a bat file, when I run the bat file through CMD, it's again working fine.
When Popen through python, it showing same error. If it helps I am using python code.
p = subprocess.Popen ('bat.bat',stdout=subprocess.PIPE, stderr=subprocess.STDOUT)
print p.stdout.read()
I tried listing the classes under the namespace, the class was listed when the bat file was called through CMD, when Popen, none of Teradici's classes were available. The command line in bat.bat is
powershell Get-WmiObject -namespace "root\cimv2" -computername computer01 -list
All this is being run on VMWare VDI (Virtual Desktop Infrastructure), can there be any policy restrictions?
After troubleshooting for sometime, The reason seems like, the required class wasn't accessible from 32 bit programs, although when I tried through PowerShell (x64 & x86) I got correct responses.
Otherwise 64 bit WMI Provider can be accessed through 32 bit Program or vice versa, by correctly setting up __ProviderArchitecture & __RequiredArchitecture WMI Context flags,
a pythonic example is as follows
import win32com.client
import wmi
import os
objCtx = win32com.client.Dispatch("WbemScripting.SWbemNamedValueSet")
if self.is64Windows():
objCtx.Add ("__ProviderArchitecture", 64)
else:
objCtx.Add ("__ProviderArchitecture", 32)
objCtx.Add ("__RequiredArchitecture", True)
server = wmi.connect_server (server = "localhost", namespace="root\\cimv2", named_value_set=objCtx)
connection = wmi.WMI (wmi = server)
More information about Context Flags can be found on msdn
http://msdn.microsoft.com/en-us/library/aa393067%28v=vs.85%29.aspx
http://msdn.microsoft.com/en-us/library/aa390789%28v=vs.85%29.aspx
Additionally for WMI debugging and troubleshooting you can refer to
http://msdn.microsoft.com/en-us/library/aa394603%28v=vs.85%29.aspx
http://msdn.microsoft.com/en-us/library/aa392285%28v=vs.85%29.aspx

How to get/set/update registry value through group policy cmdlet of Windows PowerShell?

I have configured the EventForwarding Manually but I was wondeing If I could do it programmatically and I came across the Group Policy Cmdlets which seems to be the solution. Here is what I am trying to configure manually in the image below.
When I run the Get-GPO -all cmdlet I don't see any GPOs related to Event Forwarding. However when I ran the Get-GPResultantSetOfPolicy with the specified path of an XML file, I got to see my configuration of the Subscription manager of the Event Forwarding.
Question 1: Why isn't the event forwarding policy shown in Get-GPO -all result?
Question 2: How to find out the GUID of the policy I need so I can use the Get-GPRegistryValue? besides providing the Key (which I was able to find and verfiy that it has my configuration that I have done through the gpedit.msc UI.
Question 3: How to figure out the display name of the policy in question? I tried the following:
PS C:\Windows\PolicyDefinitions> Get-GPRegistryValue -Name SubscriptionManager -Key HKEY_LOCAL_MACHINE\SOFTWARE\Policies
\Microsoft\Windows\EventLog\EventForwarding\SubscriptionManager
Where I tried for the Name attribute different things like : "EventForwarding", "EventForward", "SubscriptionManager" and even "Configure target Subscription Manager".
And here is what I got :
***Get-GPRegistryValue : The command cannot be completed because a GPO that is named "SubscriptionManager" was not found
in the nfstest.stbtest.microsoft.com domain. Make sure that the GPO that is specified by the Name parameter exists in
the domain that is specified for the cmdlet. Then, run the command again.
Parameter name: Name
At line:1 char:1
+ Get-GPRegistryValue -Name SubscriptionManager -Key HKEY_LOCAL_MACHINE\SOFTWARE\P ...
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : ObjectNotFound: (Microsoft.Group...tryValueCommand:GetGPRegistryValueCommand) [Get-GPReg
istryValue], ArgumentException
+ FullyQualifiedErrorId : GpoWithNameNotFound,Microsoft.GroupPolicy.Commands.GetGPRegistryValueCommand***
Any Help regarding any of the three related questions would be appreciated.
EDIT 1:
As you can see in the image below, when I manually configure taregt subscription manager, I get the key HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\EventLog\EventForwarding\SubscriptionManager in the registry. My question for now is simple, how can I do that with cmdlets? All what I tried so far didn't create that key for me in the registry , NOT the AD.
Thanks
Sorry not sure to understand what you do. Here is a full example :
PS C:\silogix> Import-Module grouppolicy
PS C:\silogix> New-GPO -Name "MyGPO" | New-GPLink -target "OU=SousMonou,OU=MonOu,DC=dom,DC=fr" `
-linkenabled yes
GpoId : f31df409-ca35-47cd-b699-52426e2bd196
DisplayName : MyGPO
Enabled : True
Enforced : False
Target : OU=SousMonou,OU=MonOu,DC=dom,DC=fr
Order : 1
PS C:\silogix> get-gpo -all
DisplayName : Default Domain Policy
DomainName : dom.fr
Owner : DOM\Admins du domaine
Id : 31b2f340-016d-11d2-945f-00c04fb984f9
GpoStatus : AllSettingsEnabled
Description :
CreationTime : 16/09/2010 21:07:03
ModificationTime : 09/09/2011 21:04:06
UserVersion : AD Version: 0, SysVol Version: 0
ComputerVersion : AD Version: 11, SysVol Version: 11
WmiFilter :
DisplayName : Default Domain Controllers Policy
DomainName : dom.fr
Owner : DOM\Admins du domaine
Id : 6ac1786c-016f-11d2-945f-00c04fb984f9
GpoStatus : AllSettingsEnabled
Description :
CreationTime : 16/09/2010 21:07:03
ModificationTime : 06/06/2012 17:58:00
UserVersion : AD Version: 0, SysVol Version: 0
ComputerVersion : AD Version: 4, SysVol Version: 4
WmiFilter :
DisplayName : MyGPO
DomainName : dom.fr
Owner : DOM\Admins du domaine
Id : f31df409-ca35-47cd-b699-52426e2bd196
GpoStatus : AllSettingsEnabled
Description :
CreationTime : 08/06/2012 07:04:16
ModificationTime : 08/06/2012 07:04:16
UserVersion : AD Version: 0, SysVol Version: 0
ComputerVersion : AD Version: 0, SysVol Version: 0
PS C:\silogix> Set-GPRegistryValue -Name "MyGPO" -Key HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\EventLog\EventForwarding\SubscriptionManager -value "Server=https://EVTCPT:5986/wsman/SubscriptionManager/WEC" -t
ype String
PS C:\silogix> Get-GPRegistryValue -name "MyGPO" -Key "HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\EventLog\EventForwarding\SubscriptionManager"
KeyPath : SOFTWARE\Policies\Microsoft\Windows\EventLog\EventForwarding\SubscriptionManager
FullKeyPath : HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\EventLog\EventForwarding\SubscriptionManager
Hive : LocalMachine
PolicyState : Set
Value : Server=https://EVTCPT:5986/wsman/SubscriptionManager/WEC
Type : String
ValueName : 1
HasValue : True
So you can see it in GPMC.MSC.