It is my understanding that the Oracle default Windows server images leverage Cloudbase-Init alongside an Unattend.xml file to generate a password for the user, but I am curious about the specifics of this as I am attempting to create my own images with additional software pre-installed. I want to generate a random password, and explicitly not require the user to change it. With that said here is what I have tried (I have only included the generalize portion of Unattend.xml files):
Attempt #1
For my first attempt, I did my best to imitate what I could (to the best of my knowledge) tell the default images were doing. This is the same unattend and cloubase config files as extracted from a generalized instance using Oracle's default Windows 2019 Standard image. Upon using these, the user is prompted to change their password on login.
Unattend.xml
<settings pass="generalize">
<component name="Microsoft-Windows-PnpSysprep" processorArchitecture="amd64" publicKeyToken="31bf3856ad364e35" language="neutral" versionScope="nonSxS" xmlns:wcm="http://schemas.microsoft.com/WMIConfig/2002/State" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<PersistAllDeviceInstalls>true</PersistAllDeviceInstalls>
</component>
<component name="Microsoft-Windows-Deployment" processorArchitecture="amd64" publicKeyToken="31bf3856ad364e35" language="neutral" versionScope="nonSxS" xmlns:wcm="http://schemas.microsoft.com/WMIConfig/2002/State" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<RunSynchronous>
<RunSynchronousCommand wcm:action="add">
<Order>1</Order>
<Path>cmd.exe /c ""c:\Program Files\Cloudbase Solutions\Cloudbase-Init\Python\Scripts\cloudbase-init.exe" --config-file "c:\Program Files\Cloudbase Solutions\Cloudbase-Init\conf\cloudbase-init-unattend.conf" && exit 1 || exit 2"</Path>
<Description>Run Cloudbase-Init to set the hostname</Description>
<WillReboot>OnRequest</WillReboot>
</RunSynchronousCommand>
</RunSynchronous>
</component>
</settings>
cloudbase-init-unattend.conf
[DEFAULT]
username=opc
groups=Administrators
bsdtar_path=C:\Program Files\Cloudbase Solutions\Cloudbase-Init\bin\bsdtar.exe
mtools_path=C:\Program Files\Cloudbase Solutions\Cloudbase-Init\bin\
verbose=true
debug=true
logdir=C:\Program Files\Cloudbase Solutions\Cloudbase-Init\log\
logfile=cloudbase-init-unattend.log
default_log_levels=comtypes=INFO,suds=INFO,iso8601=WARN,requests=WARN
logging_serial_port_settings=COM1,9600,N,8
local_scripts_path=C:\Program Files\Cloudbase Solutions\Cloudbase-Init\LocalScripts\
metadata_services=cloudbaseinit.metadata.services.httpservice.HttpService
plugins=cloudbaseinit.plugins.windows.winrmlistener.ConfigWinRMListenerPlugin,cloudbaseinit.plugins.common.userdata.UserDataPlugin
allow_reboot=false
stop_service_on_exit=false
check_latest_version=false
Attempt #2
For my second attempt, I tried to add a command to the Unattend file that would cause the user not to be prompted to change their password. I used the same cloubase config files as in attempt #1. Upon generalization, the user was still prompted to choose a new password.
Unattend.xml
<settings pass="generalize">
<component name="Microsoft-Windows-PnpSysprep" processorArchitecture="amd64" publicKeyToken="31bf3856ad364e35" language="neutral" versionScope="nonSxS" xmlns:wcm="http://schemas.microsoft.com/WMIConfig/2002/State" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<PersistAllDeviceInstalls>true</PersistAllDeviceInstalls>
</component>
<component name="Microsoft-Windows-Deployment" processorArchitecture="amd64" publicKeyToken="31bf3856ad364e35" language="neutral" versionScope="nonSxS" xmlns:wcm="http://schemas.microsoft.com/WMIConfig/2002/State" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<RunSynchronous>
<RunSynchronousCommand wcm:action="add">
<Order>1</Order>
<Path>cmd.exe /c "net user opc /logonpasswordchg:no && exit 1 || exit 2</Path>
<Description>Ensure the opc user does not have to reset their password</Description>
<WillReboot>Never</WillReboot>
</RunSynchronousCommand>
<RunSynchronousCommand wcm:action="add">
<Order>2</Order>
<Path>cmd.exe /c ""c:\Program Files\Cloudbase Solutions\Cloudbase-Init\Python\Scripts\cloudbase-init.exe" --config-file "c:\Program Files\Cloudbase Solutions\Cloudbase-Init\conf\cloudbase-init-unattend.conf" && exit 1 || exit 2"</Path>
<Description>Run Cloudbase-Init to set the hostname</Description>
<WillReboot>OnRequest</WillReboot>
</RunSynchronousCommand>
</RunSynchronous>
</component>
</settings>
Attempt #3
For my third attempt, I changed the order of commands within the Unattend file such that the net user was told not to change their password on login after the cloudbase init configuration was processed. I once again used the same cloubase config files as in attempt #1 and #2. Upon generalization, the user was still prompted to choose a new password.
Unattend.xml
<settings pass="generalize">
<component name="Microsoft-Windows-PnpSysprep" processorArchitecture="amd64" publicKeyToken="31bf3856ad364e35" language="neutral" versionScope="nonSxS" xmlns:wcm="http://schemas.microsoft.com/WMIConfig/2002/State" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<PersistAllDeviceInstalls>true</PersistAllDeviceInstalls>
</component>
<component name="Microsoft-Windows-Deployment" processorArchitecture="amd64" publicKeyToken="31bf3856ad364e35" language="neutral" versionScope="nonSxS" xmlns:wcm="http://schemas.microsoft.com/WMIConfig/2002/State" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<RunSynchronous>
<RunSynchronousCommand wcm:action="add">
<Order>1</Order>
<Path>cmd.exe /c ""c:\Program Files\Cloudbase Solutions\Cloudbase-Init\Python\Scripts\cloudbase-init.exe" --config-file "c:\Program Files\Cloudbase Solutions\Cloudbase-Init\conf\cloudbase-init-unattend.conf" && exit 1 || exit 2"</Path>
<Description>Run Cloudbase-Init to set the hostname</Description>
<WillReboot>OnRequest</WillReboot>
</RunSynchronousCommand>
<RunSynchronousCommand wcm:action="add">
<Order>2</Order>
<Path>cmd.exe /c "net user opc /logonpasswordchg:no && exit 1 || exit 2</Path>
<Description>Ensure the opc user does not have to reset their password</Description>
<WillReboot>Never</WillReboot>
</RunSynchronousCommand>
</RunSynchronous>
</component>
</settings>
None of these approaches yielded what I was looking for. I also tried using a plugin within Cloudbase-Init to generate a password, but it seemed that perhaps the Oracle Cloud Agent overrode this, as I was completely unable to login via RDP, whereas without using the Cloudbase plugin I could login but was unable to access a desktop prior to setting a new password.
This begs the question: what isn't working here? Is this a configuration issue, or am I fundamentally misunderstanding how this process works?
I would appreciate any suggestions anybody may have, or example implementations others have created. Thanks!
Although I was unable to get the Unattend.xml file to automatically run my command, it turns out that the easiest solution was to use Cloudbase-Init userdata to supply my command. The final userdata script ended up looking like this:
rem cmd
net user opc /logonpasswordchg:no
I hope this helps anybody who finds this question in the future.