Jump to content

Search the Community

Showing results for tags 'patching'.

More search options

  • Search By Tags

    Type tags separated by commas.
  • Search By Author

Content Type


  • MSPGeek
    • The Geek Cast
    • Code of Conduct
  • ConnectWise Automate / Labtech
    • ConnectWise Automate / LabTech
    • ConnectWise Automate / LabTech - Development


  • ConnectWise Automate
    • Scripts
    • Plugins
    • SQL Snippets
    • Role Definitions
    • Automate PowerShell Code
    • Reports
    • Internal Monitors
    • Remote Monitors
  • ConnectWise Manage
    • API Interacting Code

Find results in...

Find results that contain...

Date Created

  • Start


Last Updated

  • Start


Filter by number of...


  • Start



About Me


Agent Count













Found 19 results

  1. Hi guys, First time poster and hit a bit of a snag, Automate support haven't been very helpful so I'm hoping you will come though. Our clients require their workstations to be patched every 2nd tuesday or 3rd wednesday of the month. Set days like the 1st/18th don't work for them as this could potentially land on a weekend. We have sent manual emails before now to alert them but we would like to automate this. From what I can see I can schedule scripts to send automated emails on a set date but nothing that will allow for the 2nd tuesday etc. I'm just wondering if anybody has been in a similar position and how they've tackled it? Do you use a third party email application to send recurring emails? Or am I missing something here? Thanks Stephen
  2. Hello All, I came across an oddity. When I go to a client site and run a Service list data summary across all servers for the service name wuauserv, I find the report comes back with the service state stopped. If i right click on any device and start the service and then go to the command status page i can see it execute and then finish as success. Now if i pick the same server and install a Microsoft patch on it, and then log into the same server about 20 minutes later and check the installed patches, nothing shows for that KB as installed. If i check the same systems local services i can see the Windows update service running and set as automatic (triggered start). And I go back and double check the patch install push and it says successfully, why am i not seeing it on the physical server? its a 2012 server. The GPO for updating patch has been set to disabled not enforced, so their is no GPO blocking this. does the role Windows server update service need to be installed on the server and all servers? I dont want ever server to act as a WSUS server, when we are not using it, we want to push our updates from Automate. ** also note ** That on the local server the service - windows update is set to running and auto. But in the report below it shows it as stopped. Thanks
  3. Hi Geeks I wonder if any of you have been using Appget with Automate? It is an open source package manager for Windows. It is also an open source project on Github. It can install and update 800+ apps. I tried it on one of our PCs: References: https://appget.net/ https://github.com/appget/appget
  4. Is anyone using Patch Manager to patch large client sites based on groups set by autojoin searches based on OU? I was thinking of setting up a script to populate an EDF that contained the workstations default OU, then creating an autojoin search based on that EDF. Am I trying to reinvent the wheel or is there a better way to break up 1000+ agent sites by groups for patching?
  5. We were having trouble managing workstations, especially laptops, because they were going offline overnight. This monitor/autofix setup has drastically improved the situation. Components: Install and Apply Power Plan [function script] This creates and runs a powershell script to download a .pow file, install the power plan, and apply it. This assumes that @powerplanFileSource@ has been defined and points to a .pow file in the LTShare transfer folder. So if your powerplan file is \LTShare\Transfers\PowerPlans\nosleep.pow, you will have defined powerPlanFileSource = PowerPlans\nosleep.pow This sets a variable @installAndApplyPowerPlanResult@ = success upon success, so you can check the result after calling it. Apply Power Plan [function script] This creates and runs a powershell script to apply an already installed power plan This assumes that @powerPlanName@ has been defined and is the power plan it should apply to the computer This sets a variable @applyPowerPlanResult@ = success upon success, so you can check the result after calling it. Apply [YOUR POWER PLAN NAME] [script] This script conditionally runs the two function scripts above. You set the required variables in lines 2 and 3, and it will check to see if the plan is installed or not and act accordingly. This sets a variable @autofixResult@ = success upon success, so you can check it after calling it. ~Autofix incorrect power plan [script] This is an autofix script to be called by a monitor. If called, it will run the Apply [YOUR POWER PLAN NAME] script. If the script is successful, we're fine. If the script fails, it will create a ticket with subject and body defined by lines 2 and 3 of the Then section, and if the monitor succeeds it will close the ticket with the note defined by line 2 of the Else section. On Incorrect Power Plan [monitor] This is a RAWSQL monitor that fails if your power plan isn't applied, and will be configured to use an alert template executing ~Autofix incorreect power plan. Configuration Create your power plan On a laptop, set up the desired power configuration, including lid actions. Save it with a name you want your clients to see if they go looking at their power plan. Get the GUID of your power plan with the powershell command powercfg /List Export the power plan to a .pow file with the powershell command powercfg -export "%UserProfile%\Desktop\MyPowerPlan.pow" GUID (GUID is the GUID from the previous step) Move MyPowerPlan.pow somewhere in your LTShare\Transfer Import the attached files into Automate Modify the Apply [YOUR POWER PLAN NAME] script Rename it and change the Notes section as needed Set lines 2 and 3 to the correct values for the power plan you created and the file you exported Ensure line 24 runs the "Install and Apply Power Plan script Ensure line 34 runs the "Apply Power Plan script Modify the ~Autofix incorrect power plan script Set lines 2 and 3 of the Then section and line 2 of the Else section as desired Ensure line 13 points to the Apply [YOUR POWER PLAN NAME] script Modify the On Incorrect Power Plan monitor In Configuration>Additional Condition, change pp.currentPlan != "[YOUR POWER PLAN NAME]" so it references the name of the power plan you created in step 1 (no brackets) In Configuration>Additional Condition, change WHERE AgentID=[YOUR MONINTOR ID] with the monitor id (this is set upon import) Create an alert template Go to Automation>Templates>Alert Templates (assuming automate 12) Click on New Template Name it as you like Add an alert to run the ~Autofix incorrect power plan script, applied every day all day Now it's just a vanilla monitor setup where you enable the monitor for whatever groups you want (e.g. Patching.Patch Install - Workstations, Service Plans.Windows Workstations.Managed 24x7) and set it to use the alert template you created in step 6. -rgg *thanks to @Gavsto for his rawsql writeup. It's so good I just open it by default every time I'm starting a RAWSQL monitor. ~Autofix incorrect power plan.xml Apply [YOUR POWER PLAN NAME].xml Apply Power Plan.xml incorrect_powerplan_monitor.sql Install and Apply Power Plan.xml
  6. I decided we were going to update our patch policies to have a dropdown with all 24 hours available for patching, with a set patching window of 4 hours. I wanted to have every day available to select, as well as the end of the quarter. I also wanted to be able to toggle daytime patching with an EDF. Some quick math tells us that this would be 8*24*2 groups, or 384 groups, and 384 searches for your EDFs. This would be extremely tedious, and would absolutely cripple any automate database. I also have EDFs at the computer and location level, and allow computer specific settings to overwrite location based settings. So these searches are particularly complex. So, how to accomplish this? To start with, I named all groups <Day> <Hour> Day<+/-> and nested each of them under a specific Patch Manager group, and each day under it's own group Custom Patch Manager > Fri > Fri 12 Day- Custom Patch Manager > Fri > Fri 12 Day+ Custom Patch Manager > Fri > Fri 13 Day- etc This is still a ton of work, so to generate those groups I used the following powershell scriptlet #This should be 1 higher than the current SELECT MAX(GroupID) from mastergroups; $GroupID = 3033#Change these as needed for setting up your group names, they are referenced in the 3rd query. $Day = 'End of Quarter' $pm = ('-','+')#Adjust your loops as needed as well. I happened to have a need for a +/- in my group names here $pm | Foreach-Object { For ($hour = 0; $hour -lt 24; $hour++) { #First statement uses the direct parent of whatever group you are creating, second statement has all parents in the chain for the FIND_IN_SET @" INSERT INTO MasterGroups (ParentID,Parents,NAME,Depth,fullname,Children,GroupType,`GUID`) (SELECT GroupID,CONVERT(CONCAT(Parents,GroupID,',') USING latin1), 'New Group', (SELECT `Depth` + 1 FROM `MasterGroups` WHERE `GroupId`=2552), CONVERT(CONCAT(Fullname,'.New Group') USING latin1),',',GroupType,UUID() FROM MasterGroups WHERE GroupID=2552);UPDATE MasterGroups SET Children=CONCAT(Children,'$($GroupID),') WHERE FIND_IN_SET(GroupID,'2382,1179,2384,2552');UPDATE MasterGroups SET NAME='$($Day) $($hour) Day$($_)', Permissions=0,Notes='',Template=0,GroupType=0,MaintenanceID=0,AutoJoinScript=0,MASTER=0,NetworkJoin=0,NetworkJoinOptions=0,ContactJoin=0,ContactJoinOptions=0,Priority=5,Control=0,ControlID=0,MaintWindowApplied=NOW(),LimitToParent=0 WHERE GroupID=$($GroupID);UPDATE mastergroups mg SET mg.fullname=f_GroupFullName(mg.GroupID) WHERE FIND_IN_SET(mg.groupid,'$($GroupID)'); "@ | out-file -append -filepath ".\GeneratedSQL.txt"$GroupID++} } You basically run this once for each day, using it's specific parent group . You can see here my end of quarter stuff since it's the last thing I did. This generates the SQL needed to create the groups Once the groups are created, you do the following: INSERT INTO patchgrouppolicies SELECT GroupId, `Name` AS GroupName, NULL AS Priority, 1 AS Membership, -1 AS InstallPolicy, -1 AS SoftwarePolicy, -1 AS RebootPolicy, -1 AS ComputerLevelOverride FROM mastergroups WHERE parentid IN (2552); This links the groups to the patch manager. At this point we need to create actual update policies that match the settings you want INSERT INTO installsoftwarepolicies SELECT NULL AS Id, `Name`, 5 AS UpdateMode, 7 AS `Day`, TRIM(RIGHT(SUBSTRING_INDEX(`Name`,' ',4),2)) AS StartTime, 14 AS Duration, 1 AS CustomAction, 1 AS Dates, 1170 AS MonthlyOccurrence, 0 AS LastDay, 16 AS Occurrence, 1 AS CustomDays, IF(`Name` LIKE '%+',68,64) AS `Options`, 0 AS Uptime, 0 AS CVSS, 0 AS PromptInterval, 0 AS RebootDeadline, '' AS SoftwareUpdateMessage, 0 AS IsThirdParty, '' AS BeforeScript, '' AS AfterScript, 0 AS DaysAfter, 0 AS ServiceBranch, -1 AS FeatureUpdatesDelay, -1 AS QualityUpdatesDelay FROM mastergroups WHERE parentid = 2552; This accomplishes that. For the vast majority of groups the TRIM(RIGHT(SUBSTRING_INDEX(`Name`,' ',4),2)) AS StartTime, needs to be TRIM(RIGHT(SUBSTRING_INDEX(`Name`,' ',2),2)) AS StartTime, This is just based on the number of spaces in your group name. End of Quarter 22 has 3 spaces before the time, whereas Fri 22 has only 1, so you're taking the 4th, or the second value respectively. Once this is done you need to link your newly created policies back to the groups using this query, and everything is set up and ready to go. UPDATE patchgrouppolicies JOIN installsoftwarepolicies ON patchgrouppolicies.`GroupName`=installsoftwarepolicies.`Name` SET InstallPolicy = installsoftwarepolicies.`ID Now we have to tackle the problem of not putting a million searches in your database. this is done with the following script: You'll replace the groups in step 3 with your own groupIDs that you created. The 6th step in this script is as follows: INSERT INTO subgroups (computerid,groupid) VALUES (%computerid%,( SELECT groupid FROM mastergroups WHERE `name` =( SELECT CONCAT(IF(IFNULL(efd3.Value,'Default')='Default',IF(IFNULL(efd4.Value,'Fri')='Default','Fri',IFNULL(efd4.Value,'Fri')),efd3.Value), ' ', IF(IFNULL(efd1.Value,0)=0,IF(IFNULL(efd2.Value,0)=0,1,IF(efd2.Value='Default',1,efd2.Value)),IF(efd1.Value='Default',IF(IFNULL(efd2.Value,0)=0,1,IF(efd2.Value='Default',1,efd2.Value)),efd1.Value)), ' ', IF(IFNULL(efd5.Value,0)=0,IF(IFNULL(efd6.Value,0)=0,'Day+','Day-'),IF(efd5.Value=1,'Day-','Day+'))) AS PatchGroup FROM computers LEFT JOIN extrafielddata AS efd1 ON computers.computerid=efd1.`ID` AND efd1.`ExtraFieldID`=959 LEFT JOIN extrafielddata AS efd2 ON computers.locationid=efd2.`ID` AND efd2.`ExtraFieldID`=960 LEFT JOIN extrafielddata AS efd3 ON computers.computerid=efd3.`ID` AND efd3.`ExtraFieldID`=898 LEFT JOIN extrafielddata AS efd4 ON computers.locationid=efd4.`ID` AND efd4.`ExtraFieldID`=899 LEFT JOIN extrafielddata AS efd5 ON computers.computerid=efd5.`ID` AND efd5.`ExtraFieldID`=890 LEFT JOIN extrafielddata AS efd6 ON computers.locationid=efd6.`ID` AND efd6.`ExtraFieldID`=892 WHERE computers.computerid = %computerid%))) You'll have to use your extrafield IDs. my evenly numbered ones are my location EDFs and my odd numbered ones are my computer based EDFs. At this point you now have a flexible patch management system that lets you define a starting hour and day, as well as daytime or not for any location or computer, that doesn't rely on the built in search system. You just schedule your script to run daily spread your runs out over a period of time that makes sense for your agent count
  7. Summary: I think the Automate Patch Manager's stock Daytime Patching (DTP) functions give up way too easily. So I wrote a RAWSQL monitor that you can use to drive patch delivery scripts during the day to systems missing patches. The monitor is built to use stock Patch Manager features relating to Microsoft Update Policies, so it should be pretty universal. The configured criteria as written: System is online Windows OS No servers No reboot pending Has an effective Microsoft Update Policy that has Daytime Patching enabled Has more than 0 missing updates Hasn't run a patch job that delivered updates in the past 24 hours Not actively running a Patch Install command Hasn't recently failed a Patch Install command I'm running this monitor every five minutes, with an alert action set to a straight-up Install Missing Approved Patches Now script. I'll leave that step to you folks! I just rolled this out today, and patch delivery production has been... enthusiastic. One thing I haven't done yet is trained it to avoid DTP during a system's regular overnight patch windows as governed by their Microsoft Update Policies. Right now, I'm handling that in the Alert Template, running it only from 7am to 11pm. I'd like to include something more dynamic and elegant. Watch this space! If you're not familiar with RAWSQL monitors, I'd suggest reading Gavsto's excellent blog article on the subject. Remember, if your monitor isn't running your script properly, make sure that in the alert template you've actually enabled and checked off the days on which you want the alert template to run! 'Cause if you didn't, that would be foolish (hi)! Feedback welcome! Enjoy, Geeks. SELECT DISTINCT CAST(IFNULL(PatchesMissing.MissingCount,'0') AS UNSIGNED) AS TestValue , CONCAT(computers.Name,':',computers.ComputerID) AS IdentityField , computers.ComputerID AS ComputerID , acd.NoAlerts , acd.UpTimeStart , acd.UpTimeEnd FROM computers LEFT JOIN agentcomputerdata AS acd ON computers.`ComputerID`=acd.`ComputerID` LEFT JOIN commands ON computers.`ComputerID`=commands.`ComputerID` LEFT JOIN clients ON computers.`ClientID`=Clients.`ClientID` LEFT JOIN locations ON computers.`LocationID`=Locations.`LocationID` LEFT JOIN -- Derived table full of missing patch counts (SELECT hotfix.`ComputerID`, COUNT(hotfix.`HotFixID`) AS `MissingCount` FROM hotfix WHERE hotfix.`Approved`='2' AND hotfix.`Installed`='0' GROUP BY hotfix.`ComputerID`) AS `PatchesMissing` ON Computers.`ComputerID`=PatchesMissing.ComputerID LEFT JOIN -- Derived tables full of how many patch jobs have already run today (SELECT c.`ComputerID` , COUNT(cmd.`CmdID`) AS `CmdCnt` FROM computers c LEFT JOIN commands cmd ON cmd.computerid = c.computerid AND cmd.command = 100 AND cmd.dateupdated >= CURDATE() GROUP BY cmd.`ComputerID`) AS `Jobcounts` ON computers.`ComputerID`=Jobcounts.ComputerID WHERE DATE_SUB(NOW(), INTERVAL 5 MINUTE) < computers.`LastContact` AND computers.`OS` LIKE '%Windows%' AND computers.`OS` NOT LIKE '%Server%' AND computers.`flags` & 1024 <> 1024 -- Make sure this system has not already run more than two Install Patch commands today AND Jobcounts.CmdCnt < 3 -- Make sure this system has an active, applied Windows Update policy with Daytime Patching enabled AND computers.`ComputerID` IN (SELECT DISTINCT cpp.`ComputerID` FROM computerpatchpolicies AS cpp LEFT JOIN installsoftwarepolicies AS isp ON cpp.`InstallPolicy`=isp.`ID` WHERE isp.`Options` & 4 = 4) -- Include systems with missing patches AND (CAST(IFNULL(PatchesMissing.MissingCount,'0') AS UNSIGNED)) > 0 -- Make sure the system is not already running an Install Patch command AND computers.`ComputerID` NOT IN (SELECT DISTINCT computerid FROM commands WHERE commands.`Command`IN ('100','101') AND commands.`Status` IN ('2','4')) ORDER BY (CAST(IFNULL(PatchesMissing.MissingCount,'0') AS UNSIGNED)) DESC LIMIT 10 DISCLAIMER: Use this RAWSQL monitor at your own risk! I am not responsible for what happens when you put this (or any of my other) code into your system. Also, again, this monitor by itself won't fix your patching problems, it just drives a repeated process to hurl patching scripts at systems that seem to need it. Improvements to the SQL courtesy (presumably!) @johnduprey in the comments below. Further refinements are on the way, as are more monitors to deal with things like Patch Inventory problems.
  8. Hi All, After speaking with ConnectWise, I understand there is a script from the Solution Centre called 'Windows 10 - Install Feature Update' which requires you to deploy the latest build of Windows 10 to your LTShare, but that it's only a supported feature on-prem and cloud partners currently don't have support for this.. https://docs.connectwise.com/ConnectWise_Automate/ConnectWise_Automate_Knowledge_Base_Articles/Scripting%3A_Windows_10_Install_Feature_Update_Script As a potential workaround, ConnectWise have told me I can individually place the ISO under the LTsvc\packages folder on each machine. Rather than download 50 x 4GB ISO's for a client, I thought to use the server to then have Automate copy this locally, but I'm struggling. My plan was to create an EDF whereby we can enter at the location level the path to the ISO and then call this in a variable for the Script copy as Admin but it doesn't seem to unpack the variable path and the script fails. Has anybody else had any success upgrading from 1803/1809/1903 using Automate? Any help would be appreciated!
  9. Does anyone have a solution to notifying clients of what patches will be installed automatically? We have a client that is asking that we notify them in advance of any and all patches that are to be installed on their systems and we are looking for an automatic way of doing that to ensure we are in compliance of their needs.
  10. I just spoke with Automate support since one of our servers was showing a last patched date of 6/20/2019 by Automate but we found that it had not actually been patched since November 2018. With that said, I found from Automate support that the "last patched" date includes third party patching as well. So, this server was patched by a third party patch on 6/20/2019 but Windows updates had not been installed since November 2018. I asked them if they had a better monitor to best track the agents that have not had a Windows update installed in the last 30 days but they said there wasn't one. They said there are some coming down the road, but has anyone had to create a custom monitor that monitors just for Windows updates not being installed in the last 30 days for example? My goal is to create a monitor that would find agents that have not had a Windows update installed in the last 30 days and fully exclude third party patching from that monitor.
  11. Hi there, We seem to be having a lot of problems patching in Server 2016 - is anyone else here having difficulties? A lot of our Server 2016 servers (but not all) seem to be having updates done by UpdateOrchestrator’ & not by ‘CM Automate’ (see attached screenshot) All the patch settings in Ignite seem to be the same between the Servers that are ok, and the ones that are not, and they are all in the same Patching group, so we are at a bit of a loss to understand why some are not being patched by Labtech & some are. Does anyone know where I can look further to see what is going on here? Thanks in advance, Steve.
  12. Hi all, I am looking for a way to set up a group that will allow any computer added to it to continue patching all day long as long as it has outstanding patches. I envision being able to add new computers to this group and have them run MS patching until completely updated. Currently, I set up a group and assigned the following MS Update Policy to it: Day: Custom Start Time: 12AM Duration: 23 Hours Selected all days, of every month. I then assigned the follow reboot policy: Disable reboot window, issue reboot when patching is complete. Reboot based on Patch Reboot Mode settings. Patch Reboot Mode: Now When I add a computer to this group, it initially begins patching, installs available patches, and then reboots. The computer then has additional patches that are outstanding either as follow-up patches or patches that couldn't be installed till after a reboot, but the computer doesn't attempt to install those patches until the next morning at 12AM when it hits the next patch window. How do I go about making sure that after the first set of patches are installed, the machine reboots, and then continues patching again? Is there an easy way to get this setup?
  13. I am looking to run/schedule a Patch Compliance Report. I can run this against the client only. This gives me all the workstations and servers. Since we have our servers in a different location would it be possible to run this report with the client and location thus giving me the report for just the servers? If there is a different report I need to be running please let me know that as well. What I would like to see is How Compliance is my servers. Last Patch Date and all patches approved and ready to install. Thank you! Rob
  14. We've recently ran into an issue with cumulative updates on Windows 10 machines causing the machines to bsd. Is there a way to have the cumulative updates install separately over the weekend?
  15. Geeks, Patching your Patch Engine, Microsoft’s Windows Update Agent (WUA) is an agent program that works in conjunction with Windows Server Update Services to support automated patch delivery and installation. Labtech uses this agent to help determine what patches are needed by each Windows system and deploys them. Microsoft often updates the WUA which increases the detection of missing patches more current then the installed version of WUA. This can cause you to get a perception that your patching is up to date when in actuality your massively behind. There is more to patching then just letting the approvals happen. Windows regularly updates the agent (engine) they use to manage and seek for patches. By making sure this agent stays up to date you are making sure your users PCs stay current with the latest in system and office patches. We wanted to help the fellow LabTech geeks out there with a tool to help identify and rectify systems that are falling behind with the current WUA version. So we created Patch Remedy to assist LabTech MSPs with managing WUA. The tool is very simple to use and is mostly automated. Just turn on the master switch and wait for the data to start streaming in. We also added several manual tools inside the plugin that will allow for quick remediation of several common issues with WUA. This plugin is based on this post - http://www.labtechgeek.com/forum/viewtopic.php?f=7&t=2123 https://www.plugins4labtech.com/products/patch-remedy Enjoy Cubert :ugeek:
  16. I have a simple script that will install all missing approved patches. If missing approved patches are found it will install them and create a ticket in CW. Is there a way to get the output of the Install Patch command into the ticket as well to show what was installed or if there was an error? Thanks!
  17. Hello all, A few weeks ago, I inherited the LabTech responsibilities for my company. We're using LabTech 10.5 for patching customer machines. In the past 2 weeks, I have gone from a broken, fully manual LabTech implementation to something that is starting to come together. My computers will now automatically join the correct client/location based on the custom agent installer. From there, custom auto-join searches file machines into the proper groups I've specified. These groups automatically onboard the machines and set schedules, etc, based on my group templates. I have figured out how to do some custom scripting and reporting on a schedule. However, I'm still missing the final killer piece... How do I setup my patching groups to automatically approve all Windows updates that I specify so I don't have to do it manually via the patch manager?????? I have tried various things, and I've searched these forums somewhat (maybe not exhaustively), but I'm still pulling my hair out. Based on the (terrible) documentation I've read, it seems like if my computers are A) onboarded, and B) under a "patching contract," a default script should be doing this already. However, as I said, this is an old implementation that I inherited in bad shape, so I'm not certain that it hasn't been "damaged" somehow. I've gone into the global config to where I thought this script should be, and it isn't there... Can someone please explain how automated group approval should be working in 10.5? Can anyone point me to a good howto guide maybe? If I get this done, and our clients are getting automatically patched as they should, I can then turn my attention to upgrading this software to a later version. So please (PLEASE!) help and I will be oh so grateful... Thanks all
  18. In Continuum Patch Policy, they have failure notifications in the form of tickets. It can generate ticket for patch failures after x days out of compliance and I believe this is their way of tracking recent patching failures. Is there a built-in function like this in Automate 11 or, has anyone made something like this?
  19. Plugins4Automate.com has released a new build of Patch Remedy that now handles Windows 10 version 1709. Read our blog for information of what was added to this plugin at https://www.plugins4labtech.com/blogs/blog/patch-remedy-makes-way-for-windows-10-version-1709
  • Create New...