SCCM 2012 OSD Task Sequence - Rename computer with Service Tag - sccm

I am planning to deploy Windows 10 using SCCM 2012. It is working fine, and now I just want to rename the computer to be same as its DELL service tag, and make it as part of Task Sequence. I would ideally like to use Powershell script to do so, however happy to use VBS as well, in case it isn't easy enough with PS.
Following is the Powershell script that does the job, however I can't add it as part of Task Sequence!
$sTag = Get-WmiObject -Class win32_BIOS | Select SerialNumber
$cName = 'DESKTOP' + $sTag.SerialNumber
Rename-Computer -NewName $cName
Can someone please assist?
Thanks in advance.

I think you would be better off not renaming the computer after it is already present in sccm and ad but give it a proper name before it is joined (assuming you use unknown computer support for the osd here)
In this case you should set the SCCM Variable OSDCOmputerName already within the WinPE phase like this (you can find more detailed examples e.g. here):
$sTag = Get-WmiObject -Class win32_BIOS | Select SerialNumber
$OSDComputerName = 'DESKTOP' + $sTag.SerialNumber
$TSEnv = New-Object -COMObject Microsoft.SMS.TSEnvironment
$TSEnv.Value("OSDComputerName") = $OSDComputerName
If you want to use powershell in PE you will have to modify your boot image (Right click --> Properties --> Optional Components) to include "Windows PowerShell"

Related

Find with winget.exe all packages and save the package ID and package Name with powershell

I would like to use winget to search for all packages and store them in a text file or a variable. Later on I would like to sort them in a list with "Name" and "ID". Unfortunately it seems like you cannot search just for winget package Names and IDs directly using winget.exe
What I have tried so far:
Clear-Host
if (Test-Path -path "$env:temp\download_winget"){
write-host "Folder exists. Continuing..."
}
else{
write-Host "There is no folder called winget_download!`nCreating..."
mkdir "$env:temp\download_winget"
}
$get_winget_packages = winget search . --accept-source-agreements | Out-File "$env:temp\download_winget\winget_packages.txt" -Encoding utf8
(Yes I know, you can also use winget search """")
My Output: (a sample) (using get-content "$env:temp\download_winget\winget_packages.txt")
Name ID Version Ãœbereinstimmung Quelle
-----------------------------------------------------------------------------------------------------------------------
...
...
...
Windows Package Manager Manifest Creator Microsoft.WingetCreate 1.1.2.0 winget
Remote Desktop Services Infrastructure A… Microsoft.WindowsVirtualDesktopAge… 1.0.5739.9800 winget
Windows Terminal Preview Microsoft.WindowsTerminal.Preview 1.16.3463.0 winget
Windows Admin Center Microsoft.WindowsAdminCenter 1.3.53858.0 winget
Windows Assessment and Deployment Kit Microsoft.WindowsADK 10.1.22621.1 winget
...
...
...
As you can see, I displayed with gc "$env:temp\download_winget\winget_packages.txt" the content of the earlier created file. Unfortunately some of the lines are not displayed correctly. For example:
Remote Desktop Services Infrastructure A… Microsoft.WindowsVirtualDesktopAge… 1.0.5739.9800 winget
I did not find any solution to get all winget packages full Name or full ID using winget search .
Even running this directly in PowerShell or CMD, it will display some package Names and ID not fully. Changing the Encoding to utf32, ascii, utf7 or something else wont change anything too.
Is there a workaround to show the correct/full names of all winget packages Name and ID?
I even tried it with a new powershell process with windowstyle maximized:
Start-Process powershell.exe -ArgumentList ("winget search ." , "| Out-File '$env:temp\download_winget\winget_packages_lol.txt' -Encoding utf8") -WindowStyle Maximized
My Output (a sample):
Name ID Version Ãœbereinstimmung Quelle
-----------------------------------------------------------------------------------------------------------------------
BitRecover Windows Live Mail Converter Wizard BitRecover.WindowsLiveMailConver 7.5 winget
or
Name ID Version Ãœbereinstimmung Quelle
-----------------------------------------------------------------------------------------------------------------------
ECLiPSe Constraint Logic Programming System Version  Coninfer.ECLiPSeCLP.7.0 7.0 #63 winget
My next steps would look like this:
$file = gc "$env:temp\download_winget\winget_packages_lol.txt"
$file | sort | Get-Unique | Set-Content "$env:temp\download_winget\winget_packages_lol.txt"
I would also work here with substrings, but as mentioned earlier this can't work if I can't get the full winget packages Name and ID.
What can I do here?
WinGet releases have started including a Microsoft.WinGet.Client powershell module in the "Assets" section.

Is there any method for getting details of all installed apps in a Windows device using shell commands

I need to get all installed applications and its details in a Windows device using shell commands. I tried using
Get-appxpackage
Get-WmiObject
wmic
Apps that were installed manually seems to be missing in the list. Please help by providing a better method.
An alternative can be to query the registry like this for example:
# HKLM - Local Machine
$InstalledSoftware = Get-ChildItem "HKLM:\Software\Microsoft\Windows\CurrentVersion\Uninstall"
foreach($obj in $InstalledSoftware){write-host $obj.GetValue('DisplayName') -NoNewline; write-host " - " -NoNewline; write-host $obj.GetValue('DisplayVersion')}
# HKCU - Current User
InstalledSoftware = Get-ChildItem "HKCU:\Software\Microsoft\Windows\CurrentVersion\Uninstall"
foreach($obj in $InstalledSoftware){write-host $obj.GetValue('DisplayName') -NoNewline; write-host " - " -NoNewline; write-host $obj.GetValue('DisplayVersion')}
Check this page out for more:
https://www.codetwo.com/admins-blog/how-to-check-installed-software-version/
Tip! Browse these locations in the registry manually before you dig in as it will help you see the structure and understand what properties are available. If the information you're seeking is not there, you might just ditch this suggestion.
For Windows 64-bit and 32-bit apps use
Get-ItemProperty HKLM:\Software\Wow6432Node\Microsoft\Windows\CurrentVersion\Uninstall\* | Select-Object DisplayName, DisplayVersion, Publisher, InstallDate | Format-Table > C:\ws\apps.txt
the C:\ws\apps.txt need to be adjusted by you, to your output path.
I found the idea here, Social MS

How can i find the DHCP server? [duplicate]

I got a client who asked me to find all of his Dhcp and DNS servers with some additional info like DC servers and operationsystem
so i decided to try sharpen my powershell skills but im still new to this so i wrote this script but i guess something is still missing because it doesnt work
EDIT: i managed to find a way to get the info i want which is the OS but it gets me back ALL the servers in the company
$servers = get-dhcpserverindc
foreach($server in $Servers){
get-adcomputer -filter {Operatinsytem -like "*windows server*"} -properties
Operatingsystem | sort name | format-table name,Operatinsytem
}
This is not too tricky. First off, you connect to a machine with the RSAT Tools installed, like an admin server, jump box, or Domain Controller, and get a list of all DHCP Servers.
$DHCPServers = Get-DhcpServerInDC
Then we use PowerShell's built in looping logic to step through each server, and check for the OS info you need.
ForEach ($DHCPServer in $DHCPServers){
$OSInfo = Get-CIMInstance -ComputerName $DHCPServer.DnsName -ClassName Win32_OperatingSystem
}
Finally, we'll modify this above to return the info you're looking for, namely the IP Address, Name, and OS Version
ForEach ($DHCPServer in $DHCPServers){
$OSInfo = Get-CIMInstance -ComputerName $DHCPServer.DnsName -ClassName Win32_OperatingSystem
[pscustomobject]#{
ServerName = $DHCPServer.DnsName;
IPAddress=$DHCPServer.IpAddress;
OS=$OSInfo.Caption
}
}
ServerName IPAddress OS
---------- --------- --
dc2016 192.168.10.1 Microsoft Windows Server 2016 Standard
From there, you can store it in a variable, make it a spreadsheet, do whatever you need to do.
Hope this helps.
If this isn't working, make sure you have enabled PowerShell Remoting first.

How to format CCM_UserAffinity output to tyoe Microsoft.PowerShell.Commands.LocalPrincipal

I am trying to create a deployment script which adds freshly deployed workstation primary users to local admin group. I utilized CCM_userAffinity class to obtain username, however - Add-LocalGroupMember does not accept its output.
Ive tried creating task sequence variable to pass into powershell script which adds to group with no success either. Preferably the solution would be integrated within deployment TS, however due to no success i have reverted to ps package deployment.
$computer = "LocalHost"
$namespace = "root\ccm\Policy\Machine"
$query = "ConsoleUser"
$PrimaryUser = Get-WmiObject -class CCM_UserAffinity -computername $computer -namespace $namespace | select-object $query | format-wide
i expected the output from -class CCM_UserAffinity to be accepted by Add-LocalGroupMember, however i get this instead -
Add-LocalGroupMember : Cannot bind parameter 'Member'. Cannot convert the "Microsoft.PowerShell.Commands.Internal.Format.FormatStartData" value of type
"Microsoft.PowerShell.Commands.Internal.Format.FormatStartData" to type "Microsoft.PowerShell.Commands.LocalPrincipal".
As you plan on using the value you retrieve and not displaying it there is no need to use something like "format-wide" which only makes the output human readable and is the reason for your FormatStartData datatype.
You can just use :
$PrimaryUser = (Get-WmiObject -class CCM_UserAffinity -computername $computer -namespace $namespace).ConsoleUser
which returns a string and that is taken by the -Member argument of Add-LocalGroupMember
One thing to keep in mind is that in theory there can be more than one ConsoleUser per machine. So the ConsoleUser might be an Array or not. If you can guarantee that there is always only one user in your environment per machine (at the point where the ts runs) you can just use it as is. Otherwise you would have to specify which user you want to use and I can of course not tell you what a good rule for that for your environment would be.
Also I hope you checked that the WMI class CCM_UserAffinity is already populated at the stage where you want to run this script, I could not tell you if this is the case.

WMIMethodException with .InstallProductKey

First off, this is my first post, so if I incorrectly posted this in the wrong location, please let me know.
So, what we're trying to accomplish is building a powershell script that we can throw on our workstation image so that once our Windows 10 boxes are done imaging, that we can click on a powershell script, have it pull the key from the BIOS, and automagically activate it. That being said, here is the script that we've put together from various sources.
(Get-WmiObject -query ‘select * from SoftwareLicensingService’).OA3xOriginalProductKey | out-file c:\license.txt
$computer = gc env:computername
$key = get-content c:\license.txt
$service = get-wmiObject -query “select * from SoftwareLicensingService” -computername $computer
$service.InstallProductKey($key) <--------THIS IS WHERE IT FAILS
$service.RefreshLicenseStatus()
We start running into the issues on the line $service.InstallProductKey($key). It seems, that no matter how we try to invoke that, it will consistently fail with the error "Exception calling "InstallProductKey"". I've even replaced the variable ($key) with the specific activation key, and it STILL fails with the same error.
The reason we have it outputting to a license txt file part way through is so that we can verify that the command is indeed pulling the product key (which it is).
At this point, I'm not sure where to go. It seems that people have tried to do this before, however, nobody has really wrapped up their posting with what worked and/or what didn't. I can't imagine that this is impossible, but I'm also not fond of wasting anymore time than needed, so anybody that has any insight into this issue, I'd be very grateful.
We've gotten it to work on two machines that were previously activated, and later deactivated, but on new machines that have been freshly imaged, and have yet to be activated, it will fail every time.
Two things as per my observation:
(Get-WmiObject -query ‘select * from SoftwareLicensingService’).OA3xOriginalProductKey | out-file c:\license.txt
I don't think that it is returning any value to your license.txt.
If yes, then I would like you to see if there is any space before and after the license key. You can use trim during getting the content from the file.
Second thing, when you are getting the content from the file make sure it is not separating into multiple lines. In that case, you have to cast it as string like [String]$key or you can call toString() method for this.
One more important thing is to refresh after the installation.
$service.RefreshLicenseStatus()
Note: Make sure you are running the shell in elevated mode.
Alternative: Try Hardcoding the values and see the result
$key = "XXXXX-XXXXX-XXXXX-XXXXX-XXXXX" # hardcode the key
$computer= "Computer01" # Hardcode the computer
$service = get-wmiObject -query "select * from SoftwareLicensingService" -computername $computer
$service.InstallProductKey($key)
$service.RefreshLicenseStatus()
For further thing ,please post the exact error.
Hope it helps...!!!
Found out that the key from Get-WmiObject has whitespace on the end. The original command will work if a .Trim() is added. Also not running as administrator will result in the same error.
(Get-WmiObject -query ‘select * from SoftwareLicensingService’).OA3xOriginalProductKey | out-file c:\license.txt
$computer = gc env:computername
$key = (get-content c:\license.txt).Trim() #trim here
$service = get-wmiObject -query “select * from SoftwareLicensingService” -computername $computer
$service.InstallProductKey($key)
$service.RefreshLicenseStatus()

Resources