/// <summary> /// Approves a superseded update /// Using previous approval settings /// </summary> /// <param name="newUpdate"> /// The new update /// </param> /// <param name="previousUpdate"> /// The previously approved update /// </param> /// <param name="isTest"> /// Whether we are in test mode /// </param> /// <param name="recentlyApproved"> /// List of recently approved updates /// </param> /// <param name="shouldApproveUninstalledSupersededUpdate"> /// Whether an update that has been uninstalled should be approved if superseded. /// </param> private static void ApproveSupersededUpdate( IUpdate newUpdate, IUpdate previousUpdate, bool isTest, List <Guid> recentlyApproved, bool shouldApproveUninstalledSupersededUpdate) { if (isTest) { Console.Out.Write("(TEST) "); } Console.Out.WriteLine(newUpdate.Title); recentlyApproved.Add(newUpdate.Id.UpdateId); if (isTest) { return; } UpdateApprovalCollection approvals = previousUpdate.GetUpdateApprovals(); foreach (IUpdateApproval approval in approvals) { IComputerTargetGroup ctg = approval.GetComputerTargetGroup(); if (approval.Action == UpdateApprovalAction.Uninstall && !shouldApproveUninstalledSupersededUpdate) { // this update has been marked for removal Console.WriteLine( " WARNING: Superseded update is marked for uninstall and settings don't allow it to be automatically approved. Target group: " + ctg.Name); continue; } newUpdate.Approve(UpdateApprovalAction.Install, ctg); Console.Out.WriteLine(" " + ctg.Name); } }
/// <summary> /// Approves and update and checks for child target groups /// </summary> /// <param name="update"> /// An update /// </param> /// <param name="targetGroup"> /// A target group /// </param> /// <param name="isTest"> /// Whether we are in test mode /// </param> /// <param name="alreadyProcessed"> /// List of target groups that have already been processed /// </param> public static void ApproveUpdateForTargetGroup( IUpdate update, IComputerTargetGroup targetGroup, bool isTest, List <IComputerTargetGroup> alreadyProcessed) { if (isTest) { Console.Out.WriteLine(" (TEST)" + targetGroup.Name + "."); } else { // 1.0.0.2 issue with Adobe Flash not having an installable update if (update.InstallationBehavior.IsSupported) { if (update.IsDeclined) { Console.Out.WriteLine(" " + update.Title + ": is declined."); } else { update.Approve(UpdateApprovalAction.Install, targetGroup); Console.Out.WriteLine(" " + update.Title + ": approved for install."); } } else { Console.Out.WriteLine(" " + update.Title + ": doesn't support install approval."); } } ComputerTargetGroupCollection children = targetGroup.GetChildTargetGroups(); if (children != null && children.Count > 0) { ApproveUpdate(update, children, isTest, alreadyProcessed); } }
/// <summary> /// Approves and update and checks for child target groups /// </summary> /// <param name="update"> /// An update /// </param> /// <param name="targetGroup"> /// A target group /// </param> /// <param name="isTest"> /// Whether we are in test mode /// </param> /// <param name="alreadyProcessed"> /// List of target groups that have already been processed /// </param> public static void ApproveUpdateForTargetGroup( IUpdate update, IComputerTargetGroup targetGroup, bool isTest, List<IComputerTargetGroup> alreadyProcessed) { if (isTest) { Console.Out.WriteLine(" (TEST)" + targetGroup.Name + "."); } else { // 1.0.0.2 issue with Adobe Flash not having an installable update if (update.InstallationBehavior.IsSupported) { if (update.IsDeclined) { Console.Out.WriteLine(" " + update.Title + ": is declined."); } else { update.Approve(UpdateApprovalAction.Install, targetGroup); Console.Out.WriteLine(" " + update.Title + ": approved for install."); } } else { Console.Out.WriteLine(" " + update.Title + ": doesn't support install approval."); } } ComputerTargetGroupCollection children = targetGroup.GetChildTargetGroups(); if (children != null && children.Count > 0) { ApproveUpdate(update, children, isTest, alreadyProcessed); } }
/// <summary> /// Approves a superseded update /// Using previous approval settings /// </summary> /// <param name="newUpdate"> /// The new update /// </param> /// <param name="previousUpdate"> /// The previously approved update /// </param> /// <param name="isTest"> /// Whether we are in test mode /// </param> /// <param name="recentlyApproved"> /// List of recently approved updates /// </param> /// <param name="shouldApproveUninstalledSupersededUpdate"> /// Whether an update that has been uninstalled should be approved if superseded. /// </param> private static void ApproveSupersededUpdate( IUpdate newUpdate, IUpdate previousUpdate, bool isTest, List<Guid> recentlyApproved, bool shouldApproveUninstalledSupersededUpdate) { if (isTest) { Console.Out.Write("(TEST) "); } Console.Out.WriteLine(newUpdate.Title); recentlyApproved.Add(newUpdate.Id.UpdateId); if (isTest) { return; } UpdateApprovalCollection approvals = previousUpdate.GetUpdateApprovals(); foreach (IUpdateApproval approval in approvals) { IComputerTargetGroup ctg = approval.GetComputerTargetGroup(); if (approval.Action == UpdateApprovalAction.Uninstall && !shouldApproveUninstalledSupersededUpdate) { // this update has been marked for removal Console.WriteLine( " WARNING: Superseded update is marked for uninstall and settings don't allow it to be automatically approved. Target group: " + ctg.Name); continue; } newUpdate.Approve(UpdateApprovalAction.Install, ctg); Console.Out.WriteLine(" " + ctg.Name); } }
static void Main(string[] args) { var hook = new RemoteHook(); IUpdateServer wsusServer = ConnectLocal(); var dict = new Dictionary <string, string>(); if (args.Length > 0) { X509Certificate2 cert = DownloadSslCertificate(Environment.MachineName); switch (args[0]) { case "Set-DNSName": try { var name = args[1]; hook.SetDnsName(name); dict["value"] = "true"; hook.ReturnPayload(dict); } catch (IndexOutOfRangeException) { Console.Error.WriteLine("ERROR: missing argument: <Name>"); } break; case "Get-DNSName": dict.Add("value", hook.GetDnsName()); hook.ReturnPayload(dict); break; case "Test-SSL": dict.Add("value", wsusServer.IsConnectionSecureForApiRemoting.ToString()); hook.ReturnPayload(dict); break; case "Set-Cert": try { var path = args[1]; var pass = args[2]; SetWsusCertificate(path, pass, wsusServer); dict["value"] = "true"; hook.ReturnPayload(dict); } catch (IndexOutOfRangeException) { Console.Error.WriteLine("No Arguments found, generating new Certificate"); SetWsusCertificate(wsusServer); } break; case "Test-Conf": //Importing into other stores try { dict["value"] = "false"; X509Store store = new X509Store("WSUS", StoreLocation.LocalMachine); store.Open(OpenFlags.ReadOnly | OpenFlags.OpenExistingOnly); X509Certificate2Collection collection = (X509Certificate2Collection)store.Certificates; X509Certificate2Collection fcollection = (X509Certificate2Collection)collection.Find(X509FindType.FindByTimeValid, DateTime.Now, false); Console.WriteLine("Number of certificates: {0}{1}", fcollection.Count, Environment.NewLine); foreach (X509Certificate2 x509 in fcollection) { Console.WriteLine(x509); if (x509.GetNameInfo(X509NameType.DnsName, true) == "Carteiro") { dict["value"] = "true"; } } } catch (Exception) { dict["value"] = "false"; } hook.ReturnPayload(dict); break; case "Get-Cache": var cachePath = hook.GetCachePath(); List <Dictionary <string, string> > dataList = new List <Dictionary <string, string> >(); if (System.IO.Directory.Exists(cachePath)) { foreach (var file in System.IO.Directory.GetFiles(cachePath)) { Dictionary <string, string> entry = new Dictionary <string, string>(); entry.Add("MsiFileName", hook.GetMsiProperty(file, "ProductName")); entry.Add("PackageVersion", hook.GetMsiProperty(file, "ProductVersion")); dataList.Add(entry); } hook.ReturnPayload(dataList); } break; case "Test-Cert": if (cert != null) { if (cert.IssuerName.Name == hook.GetDnsName()) { dict["value"] = "true"; } else { dict["value"] = "false"; } } else { Console.WriteLine("ERROR: No Certificate found"); } break; case "Import-Package": try { var path = hook.GetCachePath() + args[1]; try { string desc = "Carteiro Update Package"; Console.WriteLine(path); string name = hook.GetMsiProperty(path, "ProductName"); string manufacturer = hook.GetMsiProperty(path, "Manufacturer"); string version = hook.GetMsiProperty(path, "ProductVersion"); IUpdate update = hook.ImportPackage(wsusServer, path, name, desc, manufacturer); dict.Add("Title", update.Title); dict.Add("Id", update.Id.UpdateId.ToString()); dict.Add("Manufacturer", manufacturer); dict.Add("Version", version); dict.Add("Status", "Imported"); dict.Add("CreationDate", update.CreationDate.ToString()); Console.WriteLine(dict.ToString()); } catch (Exception e) { dict.Add("Status", "Not Imported"); Console.Error.WriteLine(e); } hook.ReturnPayload(dict); } catch (IndexOutOfRangeException) { Console.Error.WriteLine("ERROR: missing argument(s)"); } break; case "Get-Package": try { var path = args[1]; var name = args[2]; dict = hook.DownloadPackage(path, name); Console.WriteLine(dict["MsiFileName"]); dict.Add("Status", "Downloaded"); hook.ReturnPayload(dict); } catch (Exception e) { dict.Add("Value", "FileNotFound"); Console.Error.WriteLine(e); hook.ReturnPayload(dict); } break; case "Get-Updates": List <Dictionary <string, string> > resUpdates = new List <Dictionary <string, string> >(); resUpdates = args.Length > 1 ? hook.GetUpdates(wsusServer, args[1]) : hook.GetUpdates(wsusServer); hook.ReturnPayload(resUpdates); break; case "Delete-Update": try { var id = args[1]; dict = hook.DeleteUpdate(wsusServer, id); hook.ReturnPayload(dict); } catch (IndexOutOfRangeException) { Console.Error.WriteLine("ERROR: missing argument(s)"); } catch (Exception e) { Console.Error.WriteLine(e); } break; //TODO Not Implemented Yet case "Approve-Update": try { var update_id = args[1]; var option = args[2]; var group_id = args[3]; Dictionary <string, string> resVal = new Dictionary <string, string>(); IUpdate update = wsusServer.GetUpdate(new UpdateRevisionId(new Guid(update_id))); IComputerTargetGroup group = wsusServer.GetComputerTargetGroup(new Guid(group_id)); switch (option) { case "Install": update.Approve(UpdateApprovalAction.Install, group); resVal.Add("Value", "installed"); break; case "Uninstall": if (update.UninstallationBehavior.IsSupported) { update.Approve(UpdateApprovalAction.Uninstall, group); resVal.Add("Value", "uninstalled"); } else { resVal.Add("Value", "not supported"); } break; case "NotApproved": try { update.Approve(UpdateApprovalAction.NotApproved, group); } catch (InvalidOperationException) { Console.Error.WriteLine("Cannot deapprove for all computers, instead declining it"); update.Decline(); resVal.Add("Value", "declined"); } resVal.Add("Value", "notApproved"); break; } update.RefreshUpdateApprovals(); hook.ReturnPayload(resVal); } catch (IndexOutOfRangeException) { Console.Error.WriteLine("ERROR: missing argument(s)"); } break; case "Get-Groups": List <Dictionary <string, string> > resGroups = new List <Dictionary <string, string> >(); resGroups = hook.GetComputerTargetGroups(wsusServer); hook.ReturnPayload(resGroups); break; case "Get-Group": try { var id = args[1]; List <Dictionary <string, string> > resList = new List <Dictionary <string, string> >(); resList = hook.GetComputerTargetGroup(wsusServer, id); hook.ReturnPayload(resList); } catch (IndexOutOfRangeException) { Console.Error.WriteLine("ERROR: missing argument(s)"); } break; case "Get-Client-Status": try { var id = args[1]; List <Dictionary <string, string> > resList = new List <Dictionary <string, string> >(); Dictionary <string, string> retDict = new Dictionary <string, string>(); retDict = hook.GetComputerTargetStatus(wsusServer, id); resList.Add(retDict); hook.ReturnPayload(resList); } catch (Exception) { Console.Error.WriteLine("ERROR: missing argument(s)"); } break; default: Console.Error.WriteLine("ERROR: invalid operation"); Console.WriteLine("\nCarteiroWin Commands:\n"); Console.WriteLine("CarteiroWin Set-DNSName <Name> : Sets a new Registry Entry for the connection to local WSUS\n"); Console.WriteLine("CarteiroWin Get-DNSName : Get connectionstring for local WSUS\n"); Console.WriteLine("CarteiroWin Test-SSL : Test if ssl connection is possible\n"); Console.WriteLine("CarteiroWin Set-Cert [Path] [Password] : Import or generate certificate into WSUS Settings\n"); Console.WriteLine("CarteiroWin Test-Conf : Test Certificate Configuration\n"); Console.WriteLine("CarteiroWin Get-Cache : Returns the current Download Cache\n"); Console.WriteLine("CarteiroWin Get-Package <Path> <Name> : Imports local Path or URL to the CarteiroWin Cache\n"); Console.WriteLine("CarteiroWin Import-Package <Filename> : Imports File from CarteiroWin Cache into WSUS\n"); Console.WriteLine("CarteiroWin Get-Updates : Returns Local Published Updates from Carteiro Win\n"); Console.WriteLine("CarteiroWin Delete-Update <update_id> : Deletes the given Update\n"); Console.WriteLine("CarteiroWin Approve-Update <update_id> <'Install'|'Uninstall'|'NotApproved'> <targetgroup_id \n: Approves the Update with the given Rule for the given WSUS group\n"); Console.WriteLine("CarteiroWin Get-Groups : Returns all WSUS TargetGroups\n"); Console.WriteLine("CarteiroWin Get-Group <id> : Returns the members of the given Group Id\n"); Console.WriteLine("CarteiroWin Get-Client-Status <id> : Returns WSUS Report for a Client\n"); break; } //hook.ReturnPayload(dict); } else { Console.WriteLine("ERROR: no Operation given"); } }