Retrive application properties from SCCM with script during a deployment - powershell

In our environment we deploy some applications with a Powershell wrapper in rare cases. For logging purposes, we want the script to retrieve properties from SCCM during installation. The properties in question are name, version and vendor. Doing some research, I figured out that I get a instance of the CCM_Application from the SCCM 2012 Client SDK:
Get-WmiObject -Namespace "Root\CCM\Clientsdk" -Class "CCM_Application" | Where {$_.EvaluationState -eq 12}
By looking for the EvaluationState value 12, I find the application in Software Center that is being currently installed. This works great for applications deployed to devices. However; when running it with applications deployed to users, it doesn't return anything. Doing some research, I discovered that CCM_Application is user centric, and the privileged service account running the script doesn't have a instance of the application.
Is there a way of making the above code work with applications deployed to users? Also; is there a better way of somehow retrieving properties from ccmexec during execution?

I know this is a very old post. The only way around this I know would be to create a scheduled task via group policy that runs as the logged in user. Trigger that, have it write it to a file, and then read it.
We were doing similar work, and we were able to get what we needed by reading appenforce.log. As crude as that is.

Related

What is the proper way to check if HyperV is running?

I am trying to write a powershell script to install and set up Hyper-V machines. The install seems to be ok, however, I get contradictory responses from the system.
Basically, I use the (gcim Win32_ComputerSystem).HypervisorPresent to determine if HyperV is running.
It return False.
There is a similar class with the same member (gcim CIM_ComputerSystem).HypervisorPresent what is also returning False.
Also found this question How do you check to see if Hyper-V is enabled using PowerShell?
and this state property is Enabled
Do I miss something? These queries aren't the same? Could you point if any of these are deprecated?
Am I totally fooled, and Enabled means the system is capable to run HyperV, but actually it is not running?
CIM and WMI are a long tale but the short summary is that WMI is a Microsoft implementation of the OMI Standards defined by the DMTF, the Distributed Management Task Force, to come up with an industry wide standard. So, of course, creating one new standard resulted in a bunch of different implementations, which are basically their own standard.
But otherwise CIM and WMI can be thought of as different gateways to the same information for Windows computers. Different doors to the same house. More on that history and the distinctions here.
When I run the PowerShell commands you shared (either of them) on my machine with Hyper-V present, even when running as a standard, non-admin user, I get True back for both.
You can also check to see if the BIOS firmware has virtualization enabled by looking in the CIM_Processor class.
(Get-CimInstance win32_processor).VirtualizationFirmwareEnabled
True
You could also check to see if the Windows Feature is installed but that doesn't give you the full picture (what if the Windows feature is enabled in an image applied to a machine without virtualization components enabled in the BIOS, for instance.)
[ADMIN] C:\>(Get-WindowsOptionalFeature -FeatureName Microsoft-Hyper-V-All -Online).State
Enabled
Also, that technique 👆 requires admin permissions.
Another way, and maybe the easiest is to check is to see if the Hyper-V Computer Service is running, which is needed for any VMs to launch, and can only run if everything else on the machine is done correctly to enable Hyper-V.
Get-Service vmcompute
Status Name DisplayName
------ ---- -----------
Running vmcompute Hyper-V Host Compute Service
We used to deploy servers with a MDT Task Sequence and enable Hyper-V along the way. It required reboots and special commands to run to apply the right bios settings. Then, we could enable the Windows Features, but those required two reboots, so it was quite tricky to handle with most imaging systems. Our final 'Sanity Check' was whether the Hyper-V compute service was running.

Powershell Script to list all Domain connected hosts

I'm busy writing a script as a project to Audit Windows Servers for PCI compliance, One of the things my project lead has asked me to attempt to get to try to get a list of all hosts that are connected to a domain, however this script needs to be able to be run on any windows server without being able to import any modules, so I'm stuck with whatever tool already exists on a bare machine.
Ive already written parts of the script that can rely on the 'active directory' modules but I also need to find a way to get information without any DNS or Domain roles installed.
The closest I can get to achieving this is by using the 'netdom' command however this relies on usernames and passwords that I cannot query for in the auditing script.
Ive tried tools like nslookup and a few other things I've come across while looking for answers online, but most of it seems to rely on modules that I cannot install on the machines that the script will need to run on.
Does anyone know if this can actually be done? and if so how can I achieve this?
Edit: for a bit more clarity, I need a way to get a list of all machines in the domain from machines that are NOT a domain controller and I cannot alter these machines at all.
As per boxdog's comment "([adsisearcher]"objectcategory=computer").findall()" command works just fine

How to initiate the removal of a server from SCCM dictated from an outside source using PowerShell

I cannot determine from the System Center Configuration Manager SDK website https://learn.microsoft.com/en-us/sccm/develop/core/misc/system-center-configuration-manager-sdk how to initiate the removal of a computer from all asset collections it may be a part of.
My company now has the ability to build, deploy, and destroy virtual servers all within a few hours. All newly built servers automatically have the SCCM client installed. The current SCCM policy is to remove servers from asset groups that have been inactive for 22 days consecutive days. This is still needed for our legacy environment.
I have been informed from my VM team that there is already code that is automatically run after a virtual server is destroyed. I want to include code that can reach out to our SCCM server to initiate the removal of the server that was destroyed. I have never worked with this kind of approach before and have been unsuccessful on where to even start. I believe it was called API or Hooks.
I would prefer using PowerShell for coding as that is the language I know.
The WMI code to delete a record from sccm would be
$comp = [wmi]"\\<siteserver>\root\sms\site_<sitename>:sms_r_system.resourceID='<resourceid>'"
$comp.psbase.Delete()
To get the ResourceID you can query sms_r_system by name
(Get-WmiObject -computername <siteserver> -query "select resourceID from sms_r_system where name like '<computername>'" -Namespace "root\sms\s
ite_<sitename>").ResourceID
Keep in mind that this may produce more than one entry (which is the reason why we do not delete by name but by ResourceID, so it might be necessary to delete all of the records.
If you have access to the sccm cmdlets (only on a server where the sccm console is installed) it would be:
Get-CMDevice -Name <DeviceName> | Remove-CMDevice

Running BitsTransfer from Local Service account

I am working on making some scripts to make my job a little bit easier.
One of the things i need is too download some files to use. I first used powershell with the command Invoke-WebRequest.
It is working really well, however it dont run on windows 7 computeres, as they have powershell 2. As i have about as many windows 7 pc's as win 10 i need to find another way.
I found that Start-BitsTransfer is a good way that should work on most computeres. My problem now is, that when using the script via my remote support session it runs the script on the local service account, and then BitsTransfer wont run and gives me an error. (0x800704DD)
Is there a way to get around that problem, or any command that can be used on both win 7 and 10 and run from the local service account?
You should update PowerShell as gms0ulman states, but if you are not the person who is in charge of this decision, you have to take other steps.
This error code...
0x800704DD
The error message ERROR_NOT_LOGGED_ON, occurs because the System Event Notification Service (SENS) is not receiving user logon notifications. BITS (version 2.0 and up) depends on logon notifications from Service Control Manager, which in turn depends on the SENS service. Ensure that the SENS service is started and running correctly.
By default, BITS runs under the LocalSystem account. To modify, stop or restart BITS, you must be logged on as an administrator. In your situation, when you log on a regular account and start the PS in elevated privilege, the BITS doesn’t run under regular user account. To resolve it, you may need to configure the log on user for BITS. Please visit the following link to configure how a service is started.
Configure How a Service is Started
Services are often run with default settings — for example, a service
may be disabled automatically at startup. However, you can use the
Services snap-in to change the default settings for a service. This is
useful if you are troubleshooting service failures or if you need to
change the security account under which a service runs. Membership in
Account Operators or Domain Admins, Enterprise Admins, or equivalent,
is the minimum required to complete this procedure. Review the details
in "Additional considerations" in this topic.
https://learn.microsoft.com/en-us/previous-versions/windows/it-pro/windows-server-2008-R2-and-2008/cc755249(v=ws.10)
I also agree that you should not continue supporting PowerShell 2.0. Ideally, ditch Windows 7 (it's way too old now), if you can't do that, upgrade PowerShell, if you can't do that, find a new job, if you can't do that, then I guess bring on the workarounds!
postanote's answer covers the BITS angle.
The other thing you can do is just use the .Net framework's underlying libraries, which is exactly what Invoke-RestMethod and Invoke-WebRequest do (those cmdlets were introduced in PowerShell 3.0, but the guts of them were around much longer).
try {
$wc = New-Object -TypeName System.Net.WebClient
$wc.DownloadFile($url, $path)
finally {
$wc.Dispose()
}
Most people don't bother disposing IDisposable objects in PowerShell so you'll see a lot of shorthand around like this:
(New-Object Net.WebClient).DownloadFile($url, $path)
Which is probably fine if your script's process isn't going to be around for a while, but it's good to keep in mind in case you incorporate this into something of a larger scale.

Identify unused application pools

I intend to find out the unused application pools among tens of live app pools on each server in a web farm containing a number of servers. The app pools are isolated per website and application.
I have listed out the application pools per server using a PS script - I'm a newbie btw, however I'm unable to match the IIS logs against the website ID for the corresponding application pool to determine if any traffic is served by the website/application at all.
This is mainly for housekeeping reasons. Is there any better approach I can take to automate the entire process?
One would think this would be easier--perhaps there is an easier way, but the following is what I was able to come up with. I have never used PowerShell to manage IIS so it's likely that someone who has more expertise in the area will have a more concise approach.
import-module WebAdministration
# get a list of the application pools
$pools = dir IIS:\AppPools
# iterate through the pools and find the ones that are not used by any websites
foreach($pool in $pools){
if ((Get-WebConfigurationProperty "/system.applicationHost/sites/site/application[#applicationPool='$($pool.name)']" "machine/webroot/apphost" -name path).Count -eq 0)
{
write-host $pool.name "has no websites."
}
}